一尘不染

为什么我不能做fmt.Sprintf(“%d。%d。%d。%d”,a ...)?

go

我正在学习Go,并且一直沉迷于Go旅游(exercise-
stringer.go:https :
//tour.golang.org/methods/7)。

这是一些代码:

type IPAddr [4]byte  
// TODO: Add a "String() string" method to IPAddr.
func (a IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", a...)
}

所以我想出了IPAddris 的内部表示[4]byte,所以散布算子起作用了。但我得到:

cannot use []string literal (type []string) as type []interface {} in argument to fmt.Sprintf

有没有搞错?字符串切片也不起作用,这是怎么回事?

编辑 :对不起,我的问题中有一个错误-
错误是关于type的IPAddr,不是[]string。我在玩代码,并且粘贴了错误的输出。无论如何,多亏了peterSO和0x434D53关于Go中切片的不变性。

好吧,这提出了另一个问题。为什么以这种方式实施?我想您只是有一些Iterable接口,所以实现它的任何结构都将“正常工作”。

旁注
:当我第一次听说Go时,有一个大胆的声明“已编译,但富有表现力”。显式接口实现是一个很好的例子,但是诸如显式转换,缺少运算符重载之类的事情给我“
90年代Java的感觉”。很难过,因为Go似乎是一门很棒的语言。


阅读 193

收藏
2020-07-02

共1个答案

一尘不染

围棋之旅

练习:纵梁

使IPAddr类型工具fmt.Stringer将地址打印为点分四边形。

例如,IPAddr{1, 2, 3, 4}应打印为"1.2.3.4“。

package main

import "fmt"

type IPAddr [4]byte

// TODO: Add a "String() string" method to IPAddr.

func main() {
  addrs := map[string]IPAddr{
      "loopback":  {127, 0, 0, 1},
      "googleDNS": {8, 8, 8, 8},
  }
  for n, a := range addrs {
      fmt.Printf("%v: %v\n", n, a)
  }
}

有没有隐式转换[]string[]interface {}。见转换的围棋语言的编程规范。您需要提供显式转换。例如,

package main

import "fmt"

type IPAddr [4]byte

// A "String() string" method for IPAddr.
func (a IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", a[0], a[1], a[2], a[3])
}

func main() {
    addrs := map[string]IPAddr{
        "loopback":  {127, 0, 0, 1},
        "googleDNS": {8, 8, 8, 8},
    }
    for n, a := range addrs {
        fmt.Printf("%v: %v\n", n, a)
    }
}

输出:

loopback: 127.0.0.1
googleDNS: 8.8.8.8
2020-07-02