为什么我不能这样做fmt.Sprintf("%d。%d。%d。%d" a ...)? [英] Why can't I do fmt.Sprintf("%d.%d.%d.%d", a...)?

查看:168
本文介绍了为什么我不能这样做fmt.Sprintf("%d。%d。%d。%d" a ...)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在学习Go,并且被Go游览卡住(exercise-stringer.go: https ://tour.golang.org/methods/7 )。



以下是一些代码:

 键入IPAddr [4] byte 
// TODO:向IPAddr添加一个String()字符串方法。
func(a IPAddr)String()string {
return fmt.Sprintf(%d。%d。%d。%d,a ...)
}

所以我认为 IPAddr 的内部表示是 [4] byte ,所以扩展运算符工作。但是我得到:

pre $ 不能使用[] string literal(type [] string)as type [] interface {} in参数为fmt.Sprintf

到底是什么?字符串切片也不起作用,这里发生了什么?


$ b 编辑:对不起,我的问题出错了 - 错误与类型 IPAddr ,而不是 []字符串。我在玩代码,并且粘贴了错误的输出。无论如何,感谢 peterSO 0x434D53 关于Go中切片的不变性。

那么,这又引发了另一个问题。为什么这样实施?我想你只有一些 Iterable 接口,所以实现它的任何结构都会正常工作。



Sidenote :当我第一次听说Go的时候,这个大胆的陈述编译,但表达。显式的接口实现就是这方面的一个很好的例子,但是显式转换,运算符重载等缺乏让我有90年代的Java感觉。这很让人伤心,因为Go似乎是一种很棒的语言。

Go Tour of Go



练习:击球手



使 IPAddr 类型的工具 fmt.Stringer 将地址打印为

$ b

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

 包主

导入fmt

类型IPAddr [4]字节

// TODO:向IPAddr添加一个String()字符串方法。

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 {} 的隐式转换。请参阅转换 =nofollow> Go编程语言规范。你需要提供一个明确的转换。例如,

 包主

导入fmt

类型IPAddr [4] byte

// IPAddr的String()string方法。
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:=范围addrs {
fmt.Printf( %v:%v \ n,n,a)
}
}

输出:

  loopback:127.0.0.1 
googleDNS:8.8.8.8

code>


I'm learning Go and I'm stuck with Go tour (exercise-stringer.go: https://tour.golang.org/methods/7).

Here's some code:

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...)
}

So I figured the inner representation of IPAddr is [4]byte, so spread operator works. But I'm getting:

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

What the heck? String slice doesn't work either, what's going on here?

EDIT: Sorry, there's an error in my question - error was about type IPAddr, not []string. I was playing with the code and I've pasted wrong output. Anyway, thanks to peterSO and 0x434D53 about invariance of slices in Go.

Well, this raises another question. Why is it implemented in this way? I imagine you'd just have some Iterable interface, so any struct implementing it would "just work".

Sidenote: when I first heard about Go there was this bold statement "compiled, but expressive". And explicit interface implementation is great example of this, but things like explicit conversion, lack of operator overloading and so on give me "90s Java feel". Which is sad, because Go seems like a great language.

解决方案

A Tour of Go

Exercise: Stringers

Make the IPAddr type implement fmt.Stringer to print the address as a dotted quad.

For instance, IPAddr{1, 2, 3, 4} should print as "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)
  }
}

There is no implicit conversion of []string to []interface {}. See Conversions in The Go Programming Language Specification. You need to provide an explicit conversion. For example,

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)
    }
}

Output:

loopback: 127.0.0.1
googleDNS: 8.8.8.8

这篇关于为什么我不能这样做fmt.Sprintf("%d。%d。%d。%d" a ...)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆