dragon8837
2013-03-14 15:30 阅读 81
已采纳

如何使fmt.Scanln()读入整数切片

I have a line containing 3 numbers that I want to read from stdin with fmt.Scanln() but this code won't work:

X := make([]int, 3)
fmt.Scanln(X...)
fmt.Printf("%v
", X)

I get this error message:

cannot use X (type []int) as type []interface {} in function argument

I don't get it.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

4条回答 默认 最新

  • 已采纳
    dpmopn8542 dpmopn8542 2013-03-14 18:01

    For example,

    package main
    
    import "fmt"
    
    func intScanln(n int) ([]int, error) {
        x := make([]int, n)
        y := make([]interface{}, len(x))
        for i := range x {
            y[i] = &x[i]
        }
        n, err := fmt.Scanln(y...)
        x = x[:n]
        return x, err
    }
    
    func main() {
        x, err := intScanln(3)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("%v
    ", x)
    }
    

    Input:

    1 2 3
    

    Output:

    [1 2 3]
    
    点赞 评论 复制链接分享
  • doushan3511 doushan3511 2013-03-14 16:01

    I think the the correct version should be

    X := make([]int, 3)
    fmt.Scanln(&X[0], &X[1], &X[2])
    fmt.Printf("%v
    ", X)
    
    点赞 评论 复制链接分享
  • doutuan6158 doutuan6158 2013-03-14 16:19

    This error message occurs b/c there's no reasonable way to convert []int to []interface{}. Note, this is in reference to a slice. So the syntax your using is correct, but fmt.Scanln expects []interface{}. This has implications outside of pkg fmt.

    The reason I've seen given for this is due to Go giving you control over memory layout so it currently has no reasonable way to do the slice conversion. This means you'll need to do the conversion manually before passing it to a function expecting the slice of a given type. For example:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        x := make([]int, 3)
        y := make([]interface{}, 3)
        y[0] = x[0]
        y[1] = x[1]
        y[2] = x[2]
    
        fmt.Println(y...)
    }
    

    Or something a little more general:

        x := make([]int, 3)
        y := make([]interface{}, len(x))
        for i, v := range x {
            y[i] = v
        }
    
        fmt.Println(y...)
    

    Regarding your specific issue, see the following:

        x := make([]*int, 3)
        for i := range x {
            x[i] = new(int)
        }
    
        y := make([]interface{}, 3)
    
        for i, v := range x {
            y[i] = v
        }
    
        if _, err := fmt.Scanln(y...); err != nil {
            fmt.Println("Scanln err: ", err)
        }
    
        for _, v := range y {
            val := v.(*int)
            fmt.Println(*val)
        }
    
    点赞 评论 复制链接分享
  • dqwh1219 dqwh1219 2015-11-19 18:33

    Idiomatic Go would be:

    func read(n int) ([]int, error) {
      in := make([]int, n)
      for i := range in {
        _, err := fmt.Scan(&in[i])
        if err != nil {
           return in[:i], err
        }
      }
      return in, nil
    }
    

    interface{} means nothing. Please don't use it if you don't have to.

    点赞 评论 复制链接分享

相关推荐