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 Matlab在app上输入带有矩阵形式的初始条件发生错误
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址
  • ¥15 elmos524.33 eeprom的读写问题
  • ¥15 用ADS设计一款的射频功率放大器