go結構體和方法
阿新 • • 發佈:2018-12-25
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
}