Go语言约定 – 从切片创建自定义类型

huangapple go评论101阅读模式
英文:

GoLang conventions - create custom type from slice

问题

在Go语言中,从切片创建自定义类型是一个不错的主意。在你的示例中,创建了一个名为Trips的自定义类型,它是[]Trip的别名。

这种做法有一些优点和缺点。以下是一些考虑因素:

优点:

  1. 提高代码的可读性:通过为切片创建自定义类型,可以更清晰地表达代码的意图。在函数签名和变量声明中使用Trips而不是[]Trip可以使代码更易于理解。
  2. 提供更好的抽象:自定义类型可以为切片提供更高层次的抽象,使代码更具可维护性和可扩展性。
  3. 可以添加自定义方法:通过为自定义类型添加方法,可以在该类型上定义特定的行为。在你的示例中,Trips类型具有TotalLength()方法,可以计算所有行程的总长度。

缺点:

  1. 增加代码复杂性:引入自定义类型可能会增加代码的复杂性,特别是在处理类型转换和函数参数传递时。
  2. 可能会引起困惑:如果在整个项目中使用了多个类似的自定义类型,可能会导致团队成员之间的困惑和不一致性。

总的来说,是否创建自定义类型取决于你的项目需求和个人偏好。如果你认为自定义类型可以提高代码的可读性和可维护性,并且可以为切片添加特定的行为,那么创建自定义类型是一个不错的选择。但如果你的项目规模较小或者没有特定的需求,直接使用[]Trip也是可以的。

英文:

Is it a good idea to create own type from a slice in Golang?

Example:

type Trip struct {
    From   string
    To     string
    Length int
}

type Trips []Trip // <-- is this a good idea?

func (trips *Trips) TotalLength() int {
    ret := 0
    for _, i := range *trips {
	    ret += i.Length
    }

    return ret
}

Is it somehow a convention in Golang to create types like Trips in my example? Or it is better to use []Trip in the whole project? Any pros and cons?

答案1

得分: 17

据我所知,目前没有任何约定。如果确实需要,创建一个切片类型是可以的。实际上,如果你想对数据进行排序,这几乎是唯一的方法:创建一个类型,并在其上定义sort.Interface方法。

此外,在你的示例中,没有必要取Trips的地址,因为切片已经是一种"fat pointer"。所以你可以简化你的方法为:

func (trips Trips) TotalLength() (tl int) {
    for _, l := range trips {
        tl += l.Length
    }
    return tl
}
英文:

There's no convention, as far as I am aware of. It's OK to create a slice type if you really need it. In fact, if you ever want to sort your data, this is pretty much the only way: create a type and define the sort.Interface methods on it.

Also, in your example there is no need to take the address of Trips since slice is already a "fat pointer" of a kind. So you can simplify your method to:

func (trips Trips) TotalLength() (tl int) {
    for _, l := range trips {
        tl += l.Length
    }
    return tl
}

答案2

得分: 8

如果这是你的类型(一个切片),那就很好。它可以方便地访问底层元素(并允许使用range进行迭代),同时提供了额外的方法。

当然,你可能只需要在这个类型上保留_必要的_方法,而不是用接受[]Trip作为参数的方法来膨胀它。(例如,我建议使用DrawTripsOnTheGlobe(t Trips)而不是将其作为Trips的方法。)

为了安抚你的心,标准包中有很多这样的切片类型:

http://golang.org/pkg/net/#IP

http://golang.org/pkg/sort/#Float64Slice

http://golang.org/pkg/sort/#IntSlice

http://golang.org/pkg/encoding/json/#RawMessage

英文:

If this is what your type is (a slice), it's just fine. It gives you an easy access to underlying elements (and allows for range iteration) while providing additional methods.

Of course you probably should only keep essential set of methods on this type and not bloating it with everything that would take []Trip as an argument. (For example I would suggest having DrawTripsOnTheGlobe(t Trips) rather than having it as a Trips' method.)

To calm your mind there are plenty of such slice-types in standard packages:

http://golang.org/pkg/net/#IP

http://golang.org/pkg/sort/#Float64Slice

http://golang.org/pkg/sort/#IntSlice

http://golang.org/pkg/encoding/json/#RawMessage

huangapple
  • 本文由 发表于 2015年7月17日 18:11:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/31473429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定