douganbi7686 2016-10-25 19:29
浏览 47
已采纳

Golang:类型分配与另一个结构

So I have this example here: Go Playground

package main

import (
    "fmt"
)

type Circle struct{}

func (c Circle) Something() {
    fmt.Println("something")
}

type Rectangle struct {
    Circle
}

func (a Rectangle) SomethingElse() {
    fmt.Println("SomethingElse")
}

type Form Rectangle

func main() {
    c := Form{}
    c.Circle.Something()
    c.SomethingElse()
}

I don't understand why I can call Something from the embedded Circle, but cannot call Somethingelse from the Rectangle within the Form type. Also I don't understand what benefit I get when I declare a type of some other type, like here in Form.

  • 写回答

3条回答 默认 最新

  • dte49889 2016-10-25 19:39
    关注

    This:

    type Form Rectangle
    

    Creates a new type named Form, having Rectangle as its underlying type.

    This means that the fields of Rectangle (which is a struct) will be defined for Form as well.

    But methods are bound to a specific type. When you create a new type (Form), that new type will not have any of the methods of its underlying type, so you can't call c.SomethingElse() as SomethingElse() is a method of the Rectangle type.

    c.Circle.Something() works, because c.Circle is a field of type Circle, and Something() is a method of the Circle type.

    If you want to call the Rectangle.SomethingElse() method, that requires a value of type Rectangle (the receiver type is Rectangle). Since underlying type of Form is Rectangle, you can simply obtain a value of type Rectangle from a value of type Form using a simple type conversion:

    Rectangle(c).SomethingElse() // This works
    

    The benefit of creating a new type is that so you can create / add your own methods for it. A common example is implementing the sort.Interface interface. Let's say you have a slice of something, e.g. []Rectangle, or a slice of some type which you have no control over (beause it's part of another package – and methods for a type can only be defined in the same package). If you want to sort this slice, you create a new type for which you can define methods, the methods of sort.Interface, e.g.:

    type SortRectangle []Rectangle
    
    func (s SortRectangle) Len() int           { return len(s) }
    func (s SortRectangle) Less(i, j int) bool { return s[i] <some-logic> s[j] }
    func (s SortRectangle) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
    

    The sort.Sort() function is able to sort any values that implement sort.Interface. The []Rectangle does not, but we just created a new type SortRectangle which does. And if we have a value of type []Rectangle, we can convert it to SortRectangle because the former is the underlying type of the latter, and by doing a conversion, we have a value of type SortRectangle which can be passed to sort.Sort(), in order to have it sorted:

    rs := []Rectangle{}
    // Sort rs:
    sort.Sort(SortRectangle(rs))
    

    Note that a conversion like the above SortRectangle(rs) only changes the runtime type information, it does not change the memory representation of rs, so it's pefectly safe and efficient.

    If you want the new type to have the methods of the "old" type, then use embedding. See Ainar-G's answer. In fact, you already did this by embedding Circle in Rectangle: the type Rectangle has a method Something(), because Something() is a method of Circle:

    Rectangle{}.Something()  // Prints "something"
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题