gpt4 book ai didi

types - 调用 Go 函数,它接受接口(interface) A 的 slice 和结构 B 的 slice (B 实现 A)

转载 作者:IT王子 更新时间:2023-10-29 01:25:34 24 4
gpt4 key购买 nike

我有以下类型:

type Statement interface {
Say() string
}

type Quote struct {
quote string
}

func (p Quote) Say() string {
return p.quote
}

func Replay(conversation []Statement) {
for _, statement := range conversation {
fmt.Println(statement.Say())
}
}

我想我已经很好地理解了为什么接受[]Statement 类型参数的函数不能用[]Quote 调用;即使 Quote 实现了 Statement[]Quote 也没有实现 []Statement[]Statement 甚至不是接口(interface)。它的类型是语句 slice 。虽然 Go 从类型隐式转换为接口(interface)类型,但它不会从类型 A 的 slice 隐式转换为接口(interface) B 的 slice 。

我们可以将引号显式转换为语句:

conversation := []Quote{
Quote{"Nice Guy Eddie: C'mon, throw in a buck!"},
Quote{"Mr. Pink: Uh-uh, I don't tip."},
Quote{"Nice Guy Eddie: You don't tip?"},
Quote{"Mr. Pink: Nah, I don't believe in it."},
Quote{"Nice Guy Eddie: You don't believe in tipping?"},
}

// This doesn't work
// Replay(conversation)

// Create statements from quotes
statements := make([]Statement, len(conversation))
for i, quote := range conversation {
statements[i] = quote
}

Replay(statements)

现在说 Replay 是一个库的一部分,该库想要在 Replay 的使用上有多么容易。它允许您使用任何对象片段调用 Replay,只要这些对象实现了 Statement 接口(interface)。为此,它具有以下转换方法:

func ConvertToStatements(its interface{}) ([]Statement, error) {
itsValue := reflect.ValueOf(its)
itsKind := itsValue.Kind()
if itsKind != reflect.Array && itsKind != reflect.Slice {
return nil, fmt.Errorf("Expected items to be an Array or a Slice, got %s", itsKind)
}
itsLength := itsValue.Len()
items := make([]Statement, itsLength)
for i := 0; i < itsLength; i++ {
itsItem := itsValue.Index(i)
if item, ok := itsItem.Interface().(Statement); ok {
items[i] = item
} else {
return nil, fmt.Errorf("item #%d does not implement the Statement interface: %s", i, itsItem)
}
}
return items, nil
}

重播看起来像这样:

func Replay(its interface{}) {
conversation := ConvertToStatements(its)
for _, statement := range conversation {
fmt.Println(statement.Say())
}
}

我们现在可以直接用引号调用 Replay:

Replay(conversation)

最后,我的问题是:是否有更简单的方法允许 Replay 接受任何类型 A 的 slice ,只要 A 实现了 Statement 接口(interface)?

最佳答案

[]Quote slice 的内存布局与 []Statement slice 不同,因此这是不可能的。

[]Quote slice 的支持数组将由顺序的 Quote 结构组成,而 []Statement slice 的支持数组包括的接口(interface)变量。除了保存 Quote 结构(或实现接口(interface)的任何其他类型),接口(interface)变量还存储指向所包含值的类型信息的指针。这是确定如何分派(dispatch) Say 方法调用所必需的。

不同的数据布局意味着您不能互换这两种 slice 类型,即使通过不安全的转换也不能:如果您有一种类型而需要另一种类型,则需要在它们之间手动转换。

关于types - 调用 Go 函数,它接受接口(interface) A 的 slice 和结构 B 的 slice (B 实现 A),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20163660/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com