首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一般切片类型在金刚?

一般切片类型在金刚?
EN

Stack Overflow用户
提问于 2014-06-18 04:47:56
回答 3查看 11.3K关注 0票数 4

在Go中,我很难将切片类型扩展到一般类型。我已经创建了一个示例代码来解释我的问题。播放地面版

代码语言:javascript
复制
package main

import "fmt"

type Sequencer interface {
    Mean() float64
}

type Sequence []int

func (s Sequence) Mean() float64 {
    sum := 0.0
    for _, el := range s {
        sum += float64(el)
    }
    return sum / float64(len(s))
}

func main() {
    a := []int{1, 2, 3, 4}
    b := Sequence(a)
    fmt.Println(b.Mean())
    fmt.Println(b[:2].Mean())
    c := Sequencer(b)
    fmt.Println(c.Mean())
    fmt.Println(c[:2].Mean())
}

main()函数的最后一行返回一个错误,说明Sequencer类型的变量不能切片:

不能分割c(Sequencer类型)

是否有一种方法来定义片的一般类型(int、float64、string、.)而不隐藏切片的酷索引功能?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-06-18 10:37:03

提供接口定义中声明的方法的任何类型都可以存储在该类型的接口变量中。当您正在存储的实际值是一个片时,任何类型都可以实现该接口。而且,由于在许多情况下不可能静态地确定接口变量的动态类型,因此如果没有显式类型断言,该语言不会让您在封面下面查看。

如果切片是您期望实现Sequencer类型的类型,那么简单的解决方案是扩展接口以包括这样的方法:

代码语言:javascript
复制
type Sequencer interface {
    Mean() float64
    Slice(start, end int) Sequencer
}

这可以以明显的方式为您的Sequence类型实现:

代码语言:javascript
复制
func (s Sequence) Slice(start, end int) Sequencer {
    return s[start:end]
}

然后,您可以使用以下方法获得切片的平均值:

代码语言:javascript
复制
fmt.Println(c.Slice(0, 2).Mean())

您可以在这里试验这个解决方案:http://play.golang.org/p/UMuqOarLUu

票数 4
EN

Stack Overflow用户

发布于 2014-06-18 10:50:50

你有

代码语言:javascript
复制
type Sequencer interface {
    Mean() float64
}

c := Sequencer(b)

因此,变量c包含满足Sequencer接口的某种类型的值;该类型有一个Mean方法。这就是我们所能说的,不多,也不差。这并不意味着可以对变量c值进行切片。因此,切片表达式c[:2]无效。例如,我们可以定义一个类型的Map,它满足Sequencer接口,但不能被切片。如果您想切片c,那么断言它是一种可以切片的类型,例如,c.(Sequence)[:2]

代码语言:javascript
复制
package main

import "fmt"

type Sequencer interface {
    Mean() float64
}

type Sequence []int

func (s Sequence) Mean() float64 {
    sum := 0.0
    for _, el := range s {
        sum += float64(el)
    }
    return sum / float64(len(s))

}

type Map map[string]float64

func (m Map) Mean() float64 {
    sum := 0.0
    for _, v := range m {
        sum += float64(v)
    }
    return sum / float64(len(m))

}

func main() {
    a := []int{1, 2, 3, 4}
    b := Sequence(a)
    fmt.Println(b.Mean())
    fmt.Println(b[:2].Mean())
    c := Sequencer(b)
    fmt.Println(c.Mean())
    fmt.Println(c.(Sequence)[:2].Mean())
    m := Map{"one": 3.14159, "two": 2.718}
    fmt.Println(m.Mean())
}

输出:

代码语言:javascript
复制
2.5
1.5
2.5
1.5
2.929795
票数 5
EN

Stack Overflow用户

发布于 2014-06-18 05:31:33

当然了。这与任何具有接口概念的其他语言没有什么不同。

您试图在不支持它的类型上调用"operator“[] -- Sequencer (接口)。然而,Sequence会这样做--因为它具有片的属性,因此对b.Meanb[:]的调用才能工作。

例如,如果这是C#,那么您实际上是在尝试这样做:

代码语言:javascript
复制
interface Sequencer {
    float Mean();
}

Sequencer c = ...;

c[any_index] ... // error - interface doesn't have this operator defined

这里的限制是不能在Go中实现操作符重载。如果可以的话-那么你就可以将它添加到界面中,并且所有的操作都会按预期进行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24277248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档