鸭子在Go中打字

时间:2012-11-06 11:16:24

标签: interface go duck-typing

我想写一个Join函数,它使用String()方法获取任意对象:

package main

import (
    "fmt"
    "strings"
)

type myint int

func (i myint) String() string {
    return fmt.Sprintf("%d", i)
}

func main() {
    parts := []myint{myint(1), myint(5), myint(6)}
    fmt.Println(Join(parts, ", "))
}

func Join(parts []fmt.Stringer, sep string) string {
    stringParts := make([]string, len(parts))
    for i, part := range(parts) {
        stringParts [i] = part.String()
    }
    return strings.Join(stringParts , sep)
}

http://play.golang.org/p/EhkbyibzHw

[]myint无法传递给Join,因为它不是fmt.Stringer类型,所以我必须写:

parts := []fmt.Stringer{myint(1), myint(5), myint(6)}

但是如果我需要parts进行另一个值必须为int的操作呢?我应该将一片myint投射到一片Stringer吗?

2 个答案:

答案 0 :(得分:6)

  

问:我应该将一片myint投射到一片Stringer吗?

Go-only转换中没有强制转换。但是,从一个具体的非接口类型到一个接口类型的片段的转换是不可能的,除非在循环中明确地进行。原因是,例如在您的情况下,[]myint支持数组的内存布局与[]fmt.Stringer不同。 (Related FAQ

在旁注中,您不必写:

parts := []myint{myint(1), myint(5), myint(6)}

这应该完全相同:

parts := []myint{1, 5, 6}

答案 1 :(得分:1)

将Join功能更改为

func Join(sep string, parts ...fmt.Stringer) string {
}

让它变得更容易:

package main

import (
    "fmt"
    "strings"
)

type myint int

func (i myint) String() string {
    return fmt.Sprintf("%d", i)
}

type myfloat float32

func (f myfloat) String() string {
    return fmt.Sprintf("%0.2f", f)
}

func main() {
    fmt.Println(Join(", ", myint(3), myfloat(3.5543)))
}

func Join(sep string, parts ...fmt.Stringer) string {
    stringParts := make([]string, len(parts))
    for i, part := range parts {
        stringParts[i] = part.String()
    }
    return strings.Join(stringParts, sep)
}