1. 程式人生 > >go結構體和方法

go結構體和方法

go結構體和方法

 

 

struct為何物

go中的struct可以實現oop中的類、方法。go語言中的struct成員可以是任何型別,如普通型別、複合型別、函式、struct、interface等。

入門

    //定義
    type User struct {
        name string
        email string
        password string
    }
    //宣告
    var user User
    var userref *User
    fmt.Println(user)    //{} 預設初始化為零值
    fmt.Println(userref) //<nil> 未初始化
    userref = new(User)
    fmt.Println(userref) //&{  }

    //初始化
    user = User{name: "liming", email: "
[email protected]
", password: "pw123456"} userref = &User{name: "liming", email: "[email protected]", password: "pw123456"} fmt.Println(user) //{liming [email protected] pw123456} fmt.Println(userref) //&{liming [email protected] pw123456} //簡單寫法 user1 := User{name: "liming", email: "
[email protected]
", password: "pw123456"} userref1 := &User{name: "liming", email: "[email protected]", password: "pw123456"} fmt.Println(user1) //{liming [email protected] pw123456} fmt.Println(userref1) //&{liming [email protected] pw123456} //引用與值的區別 upUser(user1) upUser(userref1)//cannot use userref1 (type *User) as type User in argument to upUser upUserRef(userref1) fmt.Printf("name is %s, %s", user1.name, userref1.name) //name is liming, LIMING //遞迴struct type LinkedNode struct { data string su *LinkedNode } type DoubleLinkedNode struct { pr *DoubleLinkedNode data string su *DoubleLinkedNode } type TreeNode struct { le *TreeNode data string ri *TreeNode }

進階

構造方法

oop中 , new Object(),go 通過工廠方法 NewStructName


//不強制使用建構函式,首字母大寫
type File struct {
    fd       int
    filename string
}

func NewFile(fd int, name string) *File {
    if fd < 0 {
        return nil
    }
    return &File{fd, name}
}

//強制使用建構函式,首字母小寫
type file1 struct {
    fd       int
    filename string
}

func NewFile1(fd int, name string) *file1 {
    if fd < 0 {
        return nil
    }
    return &file1{fd, name}
}

tag

可以為struct域加說明,這些說明可以通過反射獲取

type TagType struct { // tags
 field1 bool “An important answer”
 field2 string “The name of the thing”
 field3 int “How much there are”
}

匿名域

每種型別只能有一個匿名域。可以用來實現oop中的繼承


type anonymousStruct struct {
    name string
    int
    string
    File
}
    anonymous := new(anonymousStruct)
    anonymous.name = "hanmeimei"
    anonymous.int = 88
    anonymous.string = "english"
    anonymous.File.fd = 10               // or anonymous.fd = 10
    anonymous.File.filename = "xxoo.avi" //or anonymous.filename = "xxoo.avi"
    fmt.Println(anonymous)               //&{hanmeimei 88 english {10 xxoo.avi}}

方法

go語言中的oop很另類,類在go裡面叫做receiver,receiver可以是除了interface之外的任何型別。方法和類並非組織在一起,傳統的oop方法和類放在一個檔案裡面,而go語言只要在同一個包裡就可,可分散在不同檔案裡。go的理念就是資料和實現分離

Methods are not mixed with the data definition (the structs): they are orthogonal to types; representation(data) and behavior (methods) are independent

go方法定義格式如下

func (recv receiver_type) methodName(parameter_list) (return_value_list) { … }

func (_ receiver_type) methodName(parameter_list) (return_value_list) { … }

func (this receiver_type) methodName(parameter_list) (return_value_list) { … }

func (self receiver_type) methodName(parameter_list) (return_value_list) { … }


oop呼叫 object.method ,go呼叫recv.Method()

定義非struct型別方法

type IntVector []int

func (v IntVector) Sum() (s int) {
    for _, x := range v {
        s += x
    }
    return
}

方法作用域

method和receiver必須在同一個包裡定義

import “container/list”
//cannot define new methods on non-local type list.List
func (p *list.List) Iter() {
// …
}

hack方法

//hack
type myList struct {
    list.List //anonymous field
}
func (p *myList) Iter() {
    // …
}

reciever

reciever最好定義成指標的形式。對已非指標形式的reciever會自動轉換成指標形式。如

func (u *User) Iter() {
    // …
}
u:=User{"liming",22}
u.Iter() //會轉換成&User

getter setter

type Person struct {
 firstName string
 lastName string
}

func (p *Person) FirstName() string {
 return p.firstName
}
func (p *Person) SetFirstName(newName string) {
 p.firstName = newName
}