耶來到第六天了,為了介紹方便有調整了一下原先的介紹順序。今天就介紹結構跟方法,提到指標的部分可以先隨意讀一下,明天會再詳細說。
與C語言一樣,Go語言承襲了這個傳統,可使用struct
來自定義複合物件,可依照使用需要自行定義物件結構。
結構(struct)是使用者定義的類型,包含了變數命名/型態的一個集合。用於將相關數據組合在一起以形成單個單元。可以用結構來表達現實世界任何擁有屬性的實體。
type structName struct{}
type student struct {
name string
height float64
}
使用type
來宣告一種新的型別(結構),在這例子中以student為例,該型別存有兩個屬性(attribute),分別為姓名和身高。
應該算三種或四種?a
與b
兩種宣告法差在有沒有使用取址符號&
,a
是指向變數,b
是指向變數位址,在使用時要注意,以免在參數傳遞時型態出錯。
取值或更改值可直接使用「.
」來操作,很方便ˊˇˋ
func main() {
a := student{name: "Morris", height: 176.1}
b := &student{"Furry", 163.5}
c := new(student)
c.name = "BenLee"
c.height = 169.9
var d student
d.name = ("Thomas")
d.height = 175.8
}
func main(){
p := struct{
name string
height float64
}{name: "Jim", height:170.1}
fmt.Println(p.name)
fmt.Println(p.height)
}
output:
Jim 170.1
在一個struct
內可以包含另一個struct
type Student struct {
name string
height float64
contact contactInfo
}
type contactInfo struct {
email string
phoneNumber string
}
func main() {
info1 := contactInfo{"mark123@mail.com", "0912345678"}
stu1 := &Student{"Mark", 178.1, info1}
fmt.Printf("%+v\n\n", stu1)
fmt.Println("name:", stu1.name, "height:", stu1.height)
fmt.Println("mail:", stu1.email)
fmt.Println("phone:", stu1.phoneNumber)
}
output:
&{name:Mark height:178.1 contactInfo:{email:mark123@mail.com phoneNumber:0912345678}}
name: Mark height: 178.1
mail: mark123@mail.com
phone: 0912345678
仔細看會發現,我在使用Student
內contactInfo
的email
時,只使用了stu1.email
,因為在Go結構內的參數與方法是可以直接從最外層取用到的。
Go does not have classes. However, you can define methods on types.
A method is a function with a special receiver argument.
與物件導向程式不同,Go不會在class
內寫method
,而是利用receiver
來實作method
,詳情看程式碼應該比較好懂
範例為Student
增加一個名為getInfo()
的方法。
type Student struct {
name string
height float64
}
func (s Student) getInfo(){
fmt.Println("Student Name:", s.name)
fmt.Println("Height:" , s.height , "cm.")
}
func main() {
s1 := Student{"Morris", 176.4}
s1.getInfo()
}
(s Student)
,為Student
添加一個receiver function
getInfo
是函式名稱main
當中執行s1.getInfo()
時,這邊s1就是func(s Student)
中的s
上面程式碼等於為了Student
這個類別寫了一個方法,所有Student
類別的物件都可以使用getInfo
方法。
若是要更改傳入參數的值,則需要使用Pointer receivers
的方式寫函式,否則無法修改到實例的資料,先介紹錯誤範例ˊˇˋ
func (s Student) getHeight() {
fmt.Println("Height:", s.height, "cm.")
}
func (s Student) setHeight(h float64) {
s.height = h
fmt.Println("After set, height is", s.height, "cm.")
}
func main() {
s1 := Student{"Morris", 176.4}
s1.setHeight(177.0) //set success
s1.getHeight() //Height: 176.4 cm.
}
看以上這個範例,我明明呼叫了s1.setHeight(177.0)
,但實際height
並沒有被更動到。因此在做變更數值的動作時,要使用指標做為reciever
,下方程式碼為有使用Pointer receivers
的。
func (s Student) getHeight() {
fmt.Println("Height:", s.height, "cm.")
}
func (s *Student) setHeight(h float64) { // 更動這行
s.height = h
fmt.Println("set success")
}
func main() {
s1 := Student{"Morris", 176.4}
s1.setHeight(177.0)
s1.getHeight() //Height: 177 cm.
}
使用(s *Student)
做方法宣告,在變更資料時才會改到傳入的struct
。
仔細看會發現我是直接使用s1.setHeight
,是因為在Go中會自動將s1.setHeight()
看成(&s1).setHeight()
今天就介紹到這吧,function
與method
都介紹完,先進入指標再介紹程式流程,基礎的部分也快告一段落了讚讚。
[Golang] function & method 函式與方法
https://pjchender.dev/golang/function-and-method/
Golang Structs Tutorial with Examples
https://www.callicoder.com/golang-structs/
[Golang] Struct
https://pjchender.dev/golang/structs/
Golang