在golang中,可以通过在派生的自定义类型中重用基本类型的方法。

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

reusing the methods of the base type in the derived custom type in golang

问题

我想在sort.IntSlice上创建一个ReverseSort方法。所以我创建了一个名为MySlice的自定义类型,并为其添加了一个ReverseSort方法。

package main

import (
	"fmt"
	"sort"
)

type MySlice sort.IntSlice

func (ms MySlice) ReverseSort() {
	sort.Sort(sort.Reverse(ms))
}

func main() {
	t2 := MySlice{5, 4, 3, 1}
    t2.ReverseSort()
	fmt.Println(t2)
}

但是运行这个程序时出现了错误:

cannot use ms (type MySlice) as type sort.Interface in argument to sort.Reverse:
        MySlice does not implement sort.Interface (missing Len method)

有没有一种方法可以在不为我的自定义类型创建LenSwapLess方法的情况下实现这个功能?

英文:

i want to create a ReverseSort method on sort.IntSlice. So i created a custom type of MySlice and added a method of ReverseSort to it.

package main

import (
	"fmt"
	"sort"
)

type MySlice sort.IntSlice

func (ms MySlice) ReverseSort() {
	sort.Sort(sort.Reverse(ms))
}
func main() {
	t2 := MySlice{5, 4, 3, 1}
    t2.ReverseSort()
	fmt.Println(t2)
}

But on running this program error is shown that

cannot use ms (type MySlice) as type sort.Interface in argument to sort.Reverse:
        MySlice does not implement sort.Interface (missing Len method)

Is there a way by which i can implement this without creating my own Len , Swap and Less methods for my custom type.

答案1

得分: 5

你可以在自定义类型中嵌入sort.IntSlice

type MySlice struct {
    sort.IntSlice
}

func (ms MySlice) ReverseSort() {
    sort.Sort(sort.Reverse(ms))
}

func main() {
    t2 := MySlice{sort.IntSlice{5, 4, 3, 1}}
    t2.ReverseSort()
    fmt.Println(t2)
}

(在Go Playground上)

当然,这样做会使对象的构造更加困难。

golang-nuts的帖子中讨论了这个问题:

按设计,您“不能在非本地类型上定义新方法”。

最佳实践是将非本地类型嵌入到您自己的本地类型中,并进行扩展。类型别名(type MyFoo Foo)创建了一个与原始类型(more-or-less)完全不同的类型。我不知道有没有一种直接/最佳实践的方法可以使用类型断言来解决这个问题。

  • Peter Bourgon

还有:

类型的方法在定义它的包中。

这是一种逻辑上的一致性。它是一种编译优势。它被视为大规模维护和多人开发项目的重要优势。

你所说的能力并没有丧失,因为你可以像上面描述的那样将基本类型嵌入到新类型中,并添加任何你想要的内容,以实现你所寻求的“is a”功能,唯一的限制是你的新类型必须有一个新的名称,并且它的所有字段和方法必须在它的新包中。

  • Michael Jones
英文:

You could embed sort.IntSlice in your custom type:

type MySlice struct {
	sort.IntSlice
}

func (ms MySlice) ReverseSort() {
    sort.Sort(sort.Reverse(ms))
}

func main() {
    t2 := MySlice{sort.IntSlice{5, 4, 3, 1}}
    t2.ReverseSort()
    fmt.Println(t2)
}

(On the Go Playgroud.)

Of course, that makes constructing objects more difficult.


A post on golang-nuts discusses this:

> You "cannot define new methods on non-local type

展开收缩
," by design.
>
> The best practice is to embed the non-local type into your own own
> local type, and extend it. Type-aliasing (type MyFoo Foo) creates a
> type that is (more-or-less) completely distinct from the original. I'm
> not aware of a straightforward/best-practice way to use type
> assertions to get around that.
>
> - Peter Bourgon

And:

> > A type's methods are in the package that defines it.
>
> This is a logical coherence. It is a compilation virtue. It is seen as
> an important benefit for large-scale maintenance and multi-person
> development projects.
>
> The power you speak of is not lost, though, because you can embed the
> base type in a new type as described above and add whatever you want
> to it, in the kind of functional "is a" that you seek, with the only
> caveat that your new type must have a new name, and all of its fields
> and methods must be in its new package.
>
> - Michael Jones

huangapple
  • 本文由 发表于 2016年3月19日 04:55:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/36094060.html
匿名

发表评论

匿名网友

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

确定