2016-10-25 22 views
5

Vì vậy, tôi có ví dụ này ở đây: Go PlaygroundGolang: Loại gán với một struct

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() 
} 

Tôi không hiểu tại sao tôi có thể gọi Something từ nhúng Circle, nhưng không thể gọi Somethingelse từ Rectangle trong Form loại. Ngoài ra tôi không hiểu những lợi ích tôi nhận được khi tôi tuyên bố một loại của một số loại khác, như ở đây trong Form.

Trả lời

8

này:

type Form Rectangle 

Tạo một kiểu mới tên Form, có Rectangle as type tiềm ẩn của nó.

Điều này có nghĩa là các trường của Rectangle (là cấu trúc) cũng sẽ được xác định cho Form.

Nhưng các phương pháp được ràng buộc với một loại cụ thể. Khi bạn tạo một loại mới (Form), loại mới sẽ không có bất kỳ phương pháp nào thuộc loại cơ bản của nó, do đó bạn không thể gọi c.SomethingElse()SomethingElse() là một phương pháp thuộc loại Rectangle.

c.Circle.Something() hoạt động, bởi vì c.Circle là trường thuộc loại CircleSomething() là phương pháp loại Circle.

Nếu bạn muốn gọi phương thức Rectangle.SomethingElse(), yêu cầu giá trị loại Rectangle (loại người nhận là Rectangle). Kể từ loại cơ bản của FormRectangle, bạn chỉ có thể có được một giá trị kiểu Rectangle từ một giá trị kiểu Form sử dụng một kiểu đơn giản conversion:

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

Lợi ích của việc tạo ra một loại mới là để bạn có thể tạo/thêm phương pháp của riêng bạn cho nó. Một ví dụ phổ biến là triển khai giao diện sort.Interface. Giả sử bạn có một thứ gì đó, ví dụ: []Rectangle, hoặc một lát của một số loại mà bạn không có quyền kiểm soát (beause nó là một phần của gói khác - và phương pháp cho một loại chỉ có thể được xác định trong cùng một gói). Nếu bạn muốn sắp xếp lát này, bạn tạo một loại mới mà bạn có thể xác định phương pháp, phương pháp sort.Interface, ví dụ .:

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] } 

Chức năng sort.Sort() có thể sắp xếp bất kỳ giá trị mà thực hiện sort.Interface. Các []Rectangle không, nhưng chúng tôi chỉ tạo ra một loại mới SortRectangle nào.Và nếu chúng ta có giá trị loại []Rectangle, chúng ta có thể chuyển đổi thành SortRectangle vì trước đây là loại cơ bản của loại thứ hai và bằng cách thực hiện chuyển đổi, chúng tôi có giá trị loại SortRectangle có thể được chuyển đến sort.Sort(), để có nó sắp xếp:

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

Lưu ý rằng một chuyển đổi như trên SortRectangle(rs) chỉ thay đổi các thông tin kiểu thời gian chạy, nó không thay đổi đại diện ký ức về rs, do đó, nó pefectly an toànhiệu quả.

Nếu bạn muốn loại mới có các phương pháp thuộc loại "cũ", thì hãy sử dụng tính năng nhúng. Xem câu trả lời của Ainar-G. Trong thực tế, bạn đã làm điều này bằng cách nhúng Circle trong Rectangle: loại Rectangle có một phương pháp Something(), vì Something() là một phương pháp Circle:

Rectangle{}.Something() // Prints "something" 
+0

Thx để có giải thích tuyệt vời! – simplebird

1

Toàn bộ (và duy nhất) lý do để làm type Form Rectangle là xác định một mới loại với các phương thức khác nhau. Trong ví dụ của bạn: Không có phương pháp. c là một Biểu mẫu và không có phương pháp nào, chỉ có dạng raison d'être là không phải là có phương thức SomethingElse().

Nhưng một số Form vẫn nhúng một Vòng kết nối có thể truy cập dưới dạng c.Circle và đó là Circle do đó rõ ràng là có phương thức Something().

3

Quy tắc đơn giản trong Go. Nếu bạn muốn phương pháp của loại, làm

type A struct { B } 

và nếu bạn không muốn phương pháp của loại, làm

type A B 

Tại sao chúng ta cần hình thức thứ hai? Giao diện, chẳng hạn. Đôi khi, chúng tôi không muốn có giá trị để thỏa mãn giao diện, như here. Lần khác bạn chỉ cần các loại và không phải phương pháp của nó.

Đi cho bạn khả năng nhận được loại đó giống nhau, nhưng với một tập hợp phương thức trống.

Các vấn đề liên quan