企業(yè)網(wǎng)站怎么做畢業(yè)設(shè)計(jì)網(wǎng)站怎么營(yíng)銷(xiāo)推廣
Go面向“對(duì)象”編程(入門(mén)——結(jié)構(gòu)體與方法)
- 1 結(jié)構(gòu)體
- 1.1 快速入門(mén)
- 1.2 內(nèi)存解析
- 1.3 創(chuàng)建結(jié)構(gòu)體四種方法
- 1.4 注意事項(xiàng)和使用細(xì)節(jié)
- 2 方法
- 2.1 方法的聲明和調(diào)用
- 2.2 快速入門(mén)案例
- 2.3 調(diào)用機(jī)制和傳參原理
- 2.4 注意事項(xiàng)和細(xì)節(jié)
- 2.5 方法和函數(shù)區(qū)別
- 3 工廠(chǎng)模式
Golang語(yǔ)言面向?qū)ο缶幊陶f(shuō)明:
- Golang也支持面向?qū)ο缶幊?OOP),但是和傳統(tǒng)的面向?qū)ο缶幊逃袇^(qū)別,并不是純粹的面向?qū)ο笳Z(yǔ)言。所以我們說(shuō)Golang支持面向?qū)ο缶幊烫匦?/strong>是比較準(zhǔn)確的。
- Golang沒(méi)有類(lèi)(class),Go語(yǔ)言的結(jié)構(gòu)體(struct)和其它編程語(yǔ)言的類(lèi)(class)有同等的地位,你可以理解Gelang是基于struct來(lái)實(shí)現(xiàn)OOP特性的。
- Golang面向?qū)ο缶幊谭浅:?jiǎn)潔,去掉了傳統(tǒng)OOP語(yǔ)言的方法重載、構(gòu)造函數(shù)和析構(gòu)函數(shù)、隱藏的this指針等等。
- Golang仍然有面向?qū)ο缶幊痰睦^承,封裝和多態(tài)的特性,只是實(shí)現(xiàn)的方式和其它OOP語(yǔ)言不一樣,比如繼承:Golang沒(méi)有extends 關(guān)鍵字,繼承是通過(guò)匿名字段來(lái)實(shí)現(xiàn)。
- Golang面向?qū)ο?#xff08;OOP)很優(yōu)雅,OOP本身就是語(yǔ)言類(lèi)型系統(tǒng)(type system)的一部分,通過(guò)接口(interface)關(guān)聯(lián),耦合性低,也非常靈活。后面同學(xué)們會(huì)充分體會(huì)到這個(gè)特點(diǎn)。也就是說(shuō)在Golang中面向接口編程是非常重要的特性。
1 結(jié)構(gòu)體
1.1 快速入門(mén)
假設(shè)定義結(jié)構(gòu)體是老師,屬性:名字,年齡,學(xué)校
type Teacher struct {//變量名字大寫(xiě)外界可以訪(fǎng)問(wèn)這個(gè)屬性Name stringAge intSchool string
}
下面我們嘗試賦值,并打印出來(lái):
type Teacher struct {//變量名字大寫(xiě)外界可以訪(fǎng)問(wèn)這個(gè)屬性Name stringAge intSchool string
}func main() {var tea1 Teachertea1.Name = "張三"tea1.Age = 28tea1.School = "深圳大學(xué)"fmt.Println("tea1=", tea1)fmt.Println("老師的信息如下:")fmt.Println("name=", tea1.Name)fmt.Println("age=", tea1.Age)fmt.Println("school=", tea1.School)
}
輸出結(jié)果:
tea1= {張三 28 深圳大學(xué)}
老師的信息如下:
name= 張三
age= 28
school= 深圳大學(xué)
通過(guò)上面的案例和講解可以看出:
- 結(jié)構(gòu)體是自定義的數(shù)據(jù)類(lèi)型,代表一類(lèi)事務(wù)。
- 結(jié)構(gòu)體變量(實(shí)例)是具體的,實(shí)際的,代表一個(gè)具體變量。
1.2 內(nèi)存解析
在Go語(yǔ)言中,結(jié)構(gòu)體的存儲(chǔ)是在堆上。
當(dāng)我們創(chuàng)建一個(gè)結(jié)構(gòu)體實(shí)例時(shí),它的內(nèi)存將被分配在堆上。這意味著結(jié)構(gòu)體的生命周期可以超出創(chuàng)建它的函數(shù)的生命周期。
例如,當(dāng)我們使用new
關(guān)鍵字或make
函數(shù)創(chuàng)建一個(gè)結(jié)構(gòu)體實(shí)例時(shí),它將被分配在堆上。
type Person struct {Name stringAge int
}func main() {// 使用 new 關(guān)鍵字創(chuàng)建結(jié)構(gòu)體實(shí)例p := new(Person)p.Name = "Alice"p.Age = 25// 使用 make 函數(shù)創(chuàng)建結(jié)構(gòu)體實(shí)例(只適用于為某些類(lèi)型分配內(nèi)存,如 map、slice 和 channel)m := make(map[string]int)m["key"] = 42// 結(jié)構(gòu)體實(shí)例被分配在堆上,可以在其他函數(shù)中繼續(xù)使用anotherFunc(p)yetAnotherFunc(m)
}
這是因?yàn)樵贕o語(yǔ)言中,所有的變量都是通過(guò)傳值而不是通過(guò)引用傳遞。在堆上分配結(jié)構(gòu)體實(shí)例可以確保結(jié)構(gòu)體數(shù)據(jù)的持久性和可用性。
Go語(yǔ)言中結(jié)構(gòu)體的內(nèi)存布局
Go語(yǔ)言中的結(jié)構(gòu)體是一組值的集合
,這些值被存儲(chǔ)在內(nèi)存中的一段連續(xù)的區(qū)域
。結(jié)構(gòu)體的內(nèi)存布局取決于結(jié)構(gòu)體中的成員變量順序和類(lèi)型
,以及對(duì)齊方式。
結(jié)構(gòu)體的對(duì)齊方式
Go語(yǔ)言中使用的是一種稱(chēng)為Packing的方式
進(jìn)行對(duì)齊。這種方式默認(rèn)對(duì)齊到最多8字節(jié)的倍數(shù),即8字節(jié)對(duì)齊。可以通過(guò)在結(jié)構(gòu)體成員變量的后面添加逗號(hào)
和數(shù)字
的形式手動(dòng)調(diào)節(jié)對(duì)齊方式。
type Person struct {Name stringAge intHeight float64
}func main() {var p Person// 獲取結(jié)構(gòu)體的大小size := unsafe.Sizeof(p)fmt.Printf("結(jié)構(gòu)體大小:%d 字節(jié)\n", size)// 獲取結(jié)構(gòu)體字段的偏移量nameOffset := unsafe.Offsetof(p.Name)ageOffset := unsafe.Offsetof(p.Age)heightOffset := unsafe.Offsetof(p.Height)fmt.Printf("Name 字段的偏移量:%d 字節(jié)\n", nameOffset)fmt.Printf("Age 字段的偏移量:%d 字節(jié)\n", ageOffset)fmt.Printf("Height 字段的偏移量:%d 字節(jié)\n", heightOffset)// 結(jié)構(gòu)體的對(duì)齊方式packed := unsafe.Alignof(p)fmt.Printf("結(jié)構(gòu)體的對(duì)齊方式:%d 字節(jié)\n", packed)
}
輸出結(jié)果:
結(jié)構(gòu)體大小:20 字節(jié)
Name 字段的偏移量:0 字節(jié)
Age 字段的偏移量:8 字節(jié)
Height 字段的偏移量:12 字節(jié)
結(jié)構(gòu)體的對(duì)齊方式:4 字節(jié)
在這個(gè)示例中,我們定義了一個(gè)Person
結(jié)構(gòu)體,它包括名字、年齡和身高三個(gè)字段。我們通過(guò)unsafe
包中的函數(shù)來(lái)獲取結(jié)構(gòu)體的大小、字段的偏移量以及對(duì)齊方式。結(jié)構(gòu)體的大小為20字節(jié),字段的偏移量分別為0字節(jié)、8字節(jié)和12字節(jié),結(jié)構(gòu)體的對(duì)齊方式為4字節(jié)。
1.3 創(chuàng)建結(jié)構(gòu)體四種方法
基本介紹
- 從概念或叫法上:結(jié)構(gòu)體字段 = 屬性 = field
- 字段是結(jié)構(gòu)體的一個(gè)組成部分,一般是基本數(shù)據(jù)類(lèi)型、數(shù)組、也可以是引用數(shù)據(jù)類(lèi)型。
- 指針,slice和map的零值都是nil,即還沒(méi)有分配空間。
方式一:直接聲明
案例:var person Person
方式二:{}
案例:var person Person = Person{“Tom”, 18} => person := Person{“Tom”, 18}
方式三:&
案例:var person *Person = new (Person)
type Person struct {Name stringAge int
}func main() {var p *Person = new(Person)// (*p).Name = "smith" 標(biāo)準(zhǔn)寫(xiě)法// go設(shè)計(jì)者,為了程序使用方便,底層對(duì)下面這個(gè)做了優(yōu)化,實(shí)現(xiàn)了這種簡(jiǎn)單的寫(xiě)法// 會(huì)給 p 加上 取值運(yùn)算 =》 (*p).Name = "smith" p.Name = "smith" p.Age = 18fmt.Println(p)fmt.Println(*p)
}
輸出結(jié)果:
&{smith 18}
{smith 18}
方式四:{}
案例:var person *Person = &Person{}
type Person struct {Name stringAge int
}func main() {var p *Person = &Person{}// 標(biāo)準(zhǔn)方式:(*person).Name = "scott"p.Name = "scott"p.Age = 18fmt.Println(p)
}
輸出結(jié)果:&{scott 18}
1.4 注意事項(xiàng)和使用細(xì)節(jié)
- 結(jié)構(gòu)體的所有字段在內(nèi)存中是連續(xù)的,指針本身的地址是連續(xù)的,但是指向的地址不一定是連續(xù)的。
//結(jié)構(gòu)體
type Point struct {x inty int
}//結(jié)構(gòu)體
type Rect struct {leftUp, rightDown Point
}//結(jié)構(gòu)體
type Rect2 struct {leftUp, rightDown *Point
}func main() {r1 := Rect{Point{1,2}, Point{3,4}} //r1有四個(gè)int, 在內(nèi)存中是連續(xù)分布//打印地址fmt.Printf("r1.leftUp.x 地址=%p r1.leftUp.y 地址=%p r1.rightDown.x 地址=%p r1.rightDown.y 地址=%p \n", &r1.leftUp.x, &r1.leftUp.y, &r1.rightDown.x, &r1.rightDown.y)//r2有兩個(gè) *Point類(lèi)型,這個(gè)兩個(gè)*Point類(lèi)型的本身地址也是連續(xù)的,//但是他們指向的地址不一定是連續(xù)r2 := Rect2{&Point{10,20}, &Point{30,40}} //打印地址fmt.Printf("r2.leftUp 本身地址=%p r2.rightDown 本身地址=%p \n", &r2.leftUp, &r2.rightDown)//他們指向的地址不一定是連續(xù)..., 這個(gè)要看系統(tǒng)在運(yùn)行時(shí)是如何分配fmt.Printf("r2.leftUp 指向地址=%p r2.rightDown 指向地址=%p \n", r2.leftUp, r2.rightDown)
}
輸出結(jié)果:
r1.leftUp.x 地址=0x9496080 r1.leftUp.y 地址=0x9496084 r1.rightDown.x 地址=0x9496088 r1.rightDown.y 地址=0x949608c
r2.leftUp 本身地址=0x948a038 r2.rightDown 本身地址=0x948a03c
r2.leftUp 指向地址=0x9496068 r2.rightDown 指向地址=0x94960a0
-
結(jié)構(gòu)體之間可以轉(zhuǎn)換,但是有要求,就是結(jié)構(gòu)體的字段要完全一樣(包括:名字、類(lèi)型,個(gè)數(shù))
type A struct {Num int }type B struct {Num int }func main() {var a Avar b Ba = A(b)fmt.Println(a, b) }
-
結(jié)構(gòu)體進(jìn)行type重新定義(相當(dāng)于取別名),Golang認(rèn)為是新的數(shù)據(jù)類(lèi)型,但是相互間可以強(qiáng)轉(zhuǎn)。
type Student struct {Name stringAge int
}type Stu Studentfunc main() {var stu1 Studentvar stu2 Stu// stu2 = stu1 // 錯(cuò)誤,系統(tǒng)認(rèn)為這是兩個(gè)不一樣的類(lèi)型stu2 = Stu(stu1)fmt.Println(stu1, stu2)
}
-
struct的每個(gè)字段上,可以寫(xiě)上一個(gè)標(biāo)簽tag,該tag可以通過(guò)反射機(jī)制獲取,常見(jiàn)的使用場(chǎng)景就是序列化和反序列化。
type Student struct {Name string `json:"name"` // 這里就是結(jié)構(gòu)體的標(biāo)簽tagAge int `json:"age"` }func main() {// 1.創(chuàng)建一個(gè)student變量student := Student{"張三", 18}// 2.將monster變量序列化為json格式字符串jsonStr, err := json.Marshal(student) // 這里json.Marshal底層用到了反射if err != nil {fmt.Println("jsonStr報(bào)錯(cuò)")}fmt.Println("jsonStr:", jsonStr)fmt.Println("string(jsonStr):", string(jsonStr)) }
如果這里不加上標(biāo)簽,生成的json格式,就變成:
string(jsonStr): {"Name":"張三","Age":18}
會(huì)發(fā)現(xiàn),這里的Name的首字母是大寫(xiě),這又是不可避免,因?yàn)樾?xiě)就調(diào)用不了
所以這里通過(guò)標(biāo)簽,設(shè)置一個(gè)別名,底層用了反射解決這個(gè)問(wèn)題~~~
輸出結(jié)果:
string(jsonStr): {"name":"張三","age":18}
2 方法
在某些情況下,我們需要聲明(定義)方法。比如Person結(jié)構(gòu)體:除了有一些字段外(年齡,姓名…),Person結(jié)構(gòu)體還有一些行為。比如:可以說(shuō)好,跑步,學(xué)習(xí)等,還可以做算術(shù)題。這時(shí)就要用方法才能完成
Golang中的方法是作用在指定的數(shù)據(jù)類(lèi)型上的(即:和指定的數(shù)據(jù)類(lèi)型綁定),因此自定義類(lèi)型,都可以有方法,而不僅僅只是struct。
2.1 方法的聲明和調(diào)用
type A struct {Num int
}func (a A) test() {fmt.Println(a.Num)
}
對(duì)上面的語(yǔ)法說(shuō)明:
- func (a A) test() {} 表示A結(jié)構(gòu)體有一方法,方法名為 test
- (a A) 體現(xiàn)test方法是和A類(lèi)型綁定的
type Person struct {Name string
}func (p Person) test() {p.Name = "Tom"fmt.Println("test():", p.Name)
}func main() {person := Person{Name: "張三"}person.test() // 調(diào)用方法fmt.Println("main p.Name=", person.Name)
}
輸出結(jié)果:
test(): Tom
main p.Name= 張三
對(duì)上面的總結(jié):
-
test方法和Person類(lèi)型綁定
-
test方法只能通過(guò)Person類(lèi)型的遍歷來(lái)調(diào)用,而不能直接調(diào)用,也不嫩更實(shí)用其他類(lèi)型變量來(lái)調(diào)用。
-
func (p Person) test() {} 這個(gè)p是它的副本,進(jìn)行的是值傳遞,與函數(shù)很像。
2.2 快速入門(mén)案例
-
給Person結(jié)構(gòu)體添加speak 方法,輸出 xxx是一個(gè)好人
type Person struct{Name string }//給Person結(jié)構(gòu)體添加speak 方法,輸出 xxx是一個(gè)好人 func (p Person) speak() {fmt.Println(p.Name, "是一個(gè)goodman~") }
-
給Person結(jié)構(gòu)體添加jisuan 方法,可以計(jì)算從 1+…+1000的結(jié)果,
type Person struct {Name string }func (p Person) jisuan() {res := 0for i := 1; i <= 1000; i++ {res += i}fmt.Println(p.Name, "計(jì)算的結(jié)果是=", res) }func main() {p := Person{Name: "張三"}p.jisuan() // 輸出:張三 計(jì)算的結(jié)果是= 500500 }
-
給Person結(jié)構(gòu)體jisuan2 方法,該方法可以接收一個(gè)參數(shù)n,計(jì)算從 1+…+n 的結(jié)果
type Person struct {Name string }// 給Person結(jié)構(gòu)體jisuan2 方法,該方法可以接收一個(gè)參數(shù)n,計(jì)算從 1+..+n 的結(jié)果 func (p Person) jisuan2(n int) {res := 0for i := 1; i <= n; i++ {res += i}fmt.Println(p.Name, "計(jì)算的結(jié)果是=", res) }func main() {p := Person{Name: "張三"}p.jisuan2(10) // 輸出:張三 計(jì)算的結(jié)果是= 55 }
-
給Person結(jié)構(gòu)體添加getSum方法,可以計(jì)算兩個(gè)數(shù)的和,并返回結(jié)果
type Person struct {Name string }// 給Person結(jié)構(gòu)體添加getSum方法,可以計(jì)算兩個(gè)數(shù)的和,并返回結(jié)果 func (p Person) getSum(n1 int, n2 int) int {return n1 + n2 }func main() {p := Person{Name: "張三"}sum := p.getSum(1, 1)fmt.Printf("%v sum=%v", p.Name, sum) //輸出:張三 sum=2 }
2.3 調(diào)用機(jī)制和傳參原理
說(shuō)明:方法的調(diào)用和傳參機(jī)制和函數(shù)基本一樣,不一樣的地方是方法調(diào)用時(shí),會(huì)將調(diào)用方法的變量,當(dāng)作實(shí)參也傳遞給方法。下面舉例說(shuō)明:
案例:
type Person struct {Name string
}// 給Person結(jié)構(gòu)體添加getSum方法,可以計(jì)算兩個(gè)數(shù)的和,并返回結(jié)果
func (p Person) getSum(n1 int, n2 int) int {return n1 + n2
}func main() {p := Person{Name: "張三"}n1 := 10n2 := 20res := p.getSum(n1, n2)fmt.Println("res=", res)
}
- 在通過(guò)一個(gè)變量去調(diào)用方法時(shí),其調(diào)用機(jī)制和函數(shù)一樣
- 不一樣的地方是,變量調(diào)用方法時(shí),該變量本身也會(huì)作為一個(gè)參數(shù)傳遞到方法(如果變量是值類(lèi)型,則進(jìn)行值拷貝,如果是引用類(lèi)型,則進(jìn)行地質(zhì)拷貝)
2.4 注意事項(xiàng)和細(xì)節(jié)
- 結(jié)構(gòu)體類(lèi)型是值類(lèi)型,在方法調(diào)用中,遵守值類(lèi)型的傳遞機(jī)制,是值拷貝傳遞方式
- 如果程序員希望在方法中,修改結(jié)構(gòu)體變量的值,可以通過(guò)結(jié)構(gòu)體指針的方式來(lái)處理
- Golang中的方法作用在指定的數(shù)據(jù)類(lèi)型上的(即: 和指定的數(shù)據(jù)類(lèi)型綁定),因此自定義類(lèi)型,都可以有方法,而不僅僅是struct,比如int ,float32等都可以有方法
- 方法的訪(fǎng)問(wèn)范圍控制的規(guī)則,和函數(shù)一樣。方法名首字母小寫(xiě),只能在本包4訪(fǎng)問(wèn),方法首字母大寫(xiě),可以在本包和其它包訪(fǎng)問(wèn)。
- 如果一個(gè)類(lèi)型實(shí)現(xiàn)了String這個(gè)方法,那么fmt.Println默認(rèn)會(huì)調(diào)用這個(gè)變量的String()進(jìn)行輸出
上面這些注意事項(xiàng)都比較簡(jiǎn)單,就代碼展示一下最后一條:
type Student struct {Name stringAge int
}// 給*Student實(shí)現(xiàn)方法String()
func (stu *Student) String() string {str := fmt.Sprintf("Name=[%v] Age=[%v]", stu.Name, stu.Age)return str
}func main() {//定義一個(gè)Student變量stu := Student{Name: "tom",Age: 20,}//如果你實(shí)現(xiàn)了 *Student 類(lèi)型的 String方法,就會(huì)自動(dòng)調(diào)用fmt.Println(stu)fmt.Println(&stu)
}
輸出結(jié)果:
{tom 20}
Name=[tom] Age=[20]
2.5 方法和函數(shù)區(qū)別
- 調(diào)用方式不一樣
- 函數(shù)的調(diào)用方式:函數(shù)名(實(shí)參列表)
- 方法的調(diào)用方式:變量.方法名(實(shí)參列表)
- 數(shù)據(jù)傳遞的限制不一樣
- 對(duì)于普通函數(shù),接收者為值類(lèi)型時(shí),不能將指針類(lèi)型的數(shù)據(jù)直接傳遞,反之亦然。
- 對(duì)于方法(如struct的方法),接收者為值類(lèi)型時(shí),可以直接用指針類(lèi)型的遍歷調(diào)用方法,反過(guò)來(lái)同樣也可以。
這一點(diǎn)很容易迷糊,下面用段代碼解釋一下:
type Person struct {Name string
}//函數(shù)
//對(duì)于普通函數(shù),接收者為值類(lèi)型時(shí),不能將指針類(lèi)型的數(shù)據(jù)直接傳遞,反之亦然func test01(p Person) {fmt.Println(p.Name)
}func test02(p *Person) {fmt.Println(p.Name)
}//對(duì)于方法(如struct的方法),
//接收者為值類(lèi)型時(shí),可以直接用指針類(lèi)型的變量調(diào)用方法,反過(guò)來(lái)同樣也可以func (p Person) test03() {p.Name = "jack"fmt.Println("test03() =", p.Name) // jack
}func (p *Person) test04() {p.Name = "mary"fmt.Println("test03() =", p.Name) // mary
}func main() {p := Person{"tom"}test01(p)test02(&p)p.test03()fmt.Println("main() p.name=", p.Name) // tom(&p).test03() // 從形式上是傳入地址,但是本質(zhì)仍然是值拷貝fmt.Println("main() p.name=", p.Name) // tom(&p).test04()fmt.Println("main() p.name=", p.Name) // maryp.test04() // 等價(jià) (&p).test04 , 從形式上是傳入值類(lèi)型,但是本質(zhì)仍然是地址拷貝
}
輸出結(jié)果:
tom
tom
test03() = jack
main() p.name= tom
test03() = jack
main() p.name= tom
test03() = mary
main() p.name= mary
test03() = mary
從代碼會(huì)發(fā)現(xiàn),僅管傳遞的是一個(gè)地址,但是編譯器進(jìn)行了內(nèi)部?jī)?yōu)化,實(shí)際上還是值傳遞,只是支持這種寫(xiě)法,但并不是進(jìn)行一個(gè)地址值的修改。
3 工廠(chǎng)模式
說(shuō)明:Golang的結(jié)構(gòu)體沒(méi)有構(gòu)造函數(shù),通??梢允褂?strong>工廠(chǎng)模式來(lái)解決這個(gè)問(wèn)題
相當(dāng)于,這個(gè)工廠(chǎng)模式,就是以前構(gòu)造函數(shù)的功能。
看個(gè)需求:
一個(gè)結(jié)構(gòu)體的聲明如下:
package modeltype Student struct {Name string
}
因?yàn)檫@里的 Student 的首字母S是大寫(xiě)的,如果我們想在其他包串接Student的實(shí)例(比如:main包),引入model包后,就可以直接創(chuàng)建Student結(jié)構(gòu)體的變量(實(shí)例)。
但是問(wèn)題來(lái)了,如果搜字母是小寫(xiě)的,比如是: type student struct {…}就不行了,咋辦?-》工廠(chǎng)模式來(lái)解決,
Model包
package modeltype student struct {name stringscore float64
}// 因?yàn)閟tudent結(jié)構(gòu)體首字母是小寫(xiě),因此是只能在model使用
// 通過(guò)工廠(chǎng)模式來(lái)解決
func NewStudent(n string, s float64) *student {return &student{name: n,score: s,}
}// 如果score字段首字母小寫(xiě),則,在其他包不可以直接方法,我們可以提供一個(gè)方法
func (s *student) GetScore() float64 {return s.score
}// 如果score字段首字母小寫(xiě),則,在其他包不可以直接方法,我們可以提供一個(gè)方法
func (n *student) GetName() string {return n.name
}
main包
import ("GoStudy_Day1/model""fmt"
)func main() {// 定student結(jié)構(gòu)體是首字母小寫(xiě),我們可以通過(guò)工廠(chǎng)模式來(lái)解決stu := model.NewStudent("Tom", 88.8)fmt.Println(stu)fmt.Println(*stu)// fmt.Println("name=", stu.name) // 報(bào)錯(cuò),因?yàn)槭撬矫艿?/span>fmt.Println("name=", stu.GetName())fmt.Println("score=", stu.GetScore())
}
輸出結(jié)果:
&{Tom 88.8}
{Tom 88.8}
name= Tom
score= 88.8
其實(shí),這就看出來(lái),就是Java的GetSet,繞了一圈,又回來(lái)啦~~~!!!!!