第1組測試
Golang繼承中字段及方法的測試
Golang採用嵌入字段來實現繼承,由於實現上存在多種可能,這裏進行測試,看看Golang的設計思路。
待考察的問題包括:
嵌入的是結構,還是指針?
嵌入部分是匿名字段,還是命名字段?
方法是傳值,還是傳指針?
最終結論:
可以嵌入字段,也可以嵌入指針,其特性吻合慣性思維
無論字段是否指針,無論方法的接收者是否指針,在字段引用時都不區分指針
以下是測試過程
一共4組不同情形的測試
結構中有另一個結構,這是最簡單的情形
結構中有一個匿名結構,測試用類型代替字段名,或直接引用
結構中有指針指向另一個結構
結構中有匿名指針指向另一個結構
每組測3個項目
繼承後的引用
傳值方法的繼承
傳指針方法的繼承
故一共12個測試
第1組測試
結構中有另一個結構,這是最簡單的情形
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
person Person // 有另一個字段
school string
}
func main() {
anna := new(Student)
anna.person.name = "Anna"
anna.person.tel = "12345678"
//anna.school = "mit"
fmt.Printf( "My name is %s,
and my tel number is %s\n", anna.person.name, anna.person.tel)
}
第1.1組測試
結構中有另一個結構,這是最簡單的情形
測試這種情況下方法的繼承
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
person Person // 有另一個字段
school string
}
//在person上面定義了一個傳值的method
func (p Person)
Hello() {
fmt.Printf("My name is %s, and my tel number is %s\n",
p.name, p.tel)
}
func main() {
anna := new(Student)
anna.person.name = "Anna"
anna.person.tel = "2345678"
//anna.school = "mit"
// anna.Hello() // 這是不行的,非匿名字段不能直接引用
anna.person.Hello()
//fmt.Printf( "My name is %s, and my
tel number is %s\n", anna.person.name, anna.person.tel)
}
結論:
如果字段沒有匿名,則相當於中間隔了一層,不能跨越去引用
第1.2組測試
結構中有另一個結構,這是最簡單的情形
測試這種情況下方法的繼承
但是定義傳指針的method
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
person Person // 有另一個字段
school string
}
//在person上面定義了一個傳指針的method
func (p * Person)
Hello() {
fmt.Printf( "My name is %s, and my tel
number is %s\n", p.name, p.tel)
}
func main() {
anna := new(Student)
anna.person.name = "Anna"
anna.person.tel = "345678"
//anna.school = "mit"
// anna.Hello() // 這是不行的,非匿名字段不能直接引用
anna.person.Hello()
//fmt.Printf( "My name is %s, and my
tel number is %s\n", anna.person.name, anna.person.tel)
}
結論:
沒有問題,method傳值或傳指針沒有區別
第2組測試
結構中有一個匿名結構,測試用類型代替字段名,或直接引用
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
Person // 有一個匿名字段
school string
}
func main() {
anna := new(Student)
anna.Person.name = "Anna" //
用類型代替字段名
anna.tel = "123456789" //
或者直接引用
//anna.school = "mit"
fmt.Printf( "My name is %s, and my tel
number is %s\n", anna.Person.name, anna.tel)
}
第2.1組測試
結構中有一個匿名結構
測試這種情況下方法的繼承
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
Person // 有另一個字段
school string
}
//在person上面定義了一個傳值的method
func (p Person)
Hello() {
fmt.Printf("My name is %s, and my tel number is %s\n",
p.name, p.tel)
}
func main() {
anna := new(Student)
anna.Person.name = "Anna"
anna.tel = "2345"
//anna.school = "mit"
anna.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
//fmt.Printf( "My name is %s, and my
tel number is %s\n", anna.person.name, anna.person.tel)
}
結論:匿名字段,相當於匿名結構直接嵌入,在同一層面
第2.2組測試
結構中有一個匿名結構
測試這種情況下方法的繼承
但是定義傳指針的method
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
Person // 有另一個字段
school string
}
//在person上面定義了一個傳指針的method
func (p * Person)
Hello() {
fmt.Printf( "My name is %s, and my tel
number is %s\n", p.name, p.tel)
}
func main() {
anna := new(Student)
anna.Person.name = "Anna"
anna.tel = "345"
//anna.school = "mit"
anna.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
//fmt.Printf( "My name is %s, and my
tel number is %s\n", anna.person.name, anna.person.tel)
}
結論:
傳指針無影響
第3組測試
結構中有指針指向另一個結構
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
person * Person // 指針指向一個字段
school string
}
func main() {
anna := new(Student)
anna.person = new(Person) //
必須,否則panic
anna.person.name = "Anna"
anna.person.age = 22
anna.person.tel = "12345"
anna.school = "mit"
fmt.Printf( "My name is %s, and my tel
number is %s\n", anna.person.name, anna.person.tel)
}
第3.1組測試
結構中有指針指向另一個結構
測試方法的繼承
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
person * Person // 指針指向一個字段
school string
}
//在person上面定義了一個傳值的method
func (p Person)
Hello() {
fmt.Printf("My name is %s, and my tel number is %s\n",
p.name, p.tel)
}
func main() {
anna := new(Student)
anna.person = new(Person)
anna.person.name = "Anna"
anna.person.tel = "234567"
anna.person.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
}
結論:
非常正常的使用
第3.2組測試
結構中有指針指向另一個結構
測試方法的繼承
但是定義傳指針的method
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
person * Person // 指針指向一個字段
school string
}
//在person上面定義了一個傳指針的method
func (p * Person)
Hello() {
fmt.Printf( "My name is %s, and my tel
number is %s\n", p.name, p.tel)
}
func main() {
anna := new(Student)
anna.person = new(Person)
anna.person.name = "Anna"
anna.person.tel = "345678"
anna.person.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
}
結論:
指針無影響
第4組測試
結構中有匿名指針指向另一個結構
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
* Person // 匿名指針指向一個字段
school string
}
func main() {
anna := new(Student)
anna.Person = new(Person)
anna.Person.name = "Anna"
//anna.Person.age = 22
anna.tel = "123"
//anna.school = "mit"
fmt.Printf( "My name is %s, and my tel
number is %s\n", anna.Person.name, anna.tel)
}
結論:
anna.Person = new(Person) 居然也行
匿名相當於直接嵌入,在同一層面
Golang似乎是儘量識別,如果有字段名,包括指針,則必須用字段名,如果是匿名,則可用匿名字段的類型
第4.1組測試
結構中有匿名指針指向另一個結構
測試方法的繼承
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
* Person // 匿名指針指向一個字段
school string
}
//在person上面定義了一個傳值的method
func (p Person)
Hello() {
fmt.Printf("My name is %s, and my tel number is %s\n",
p.name, p.tel)
}
func main() {
anna := new(Student)
anna.Person = new(Person)
anna.Person.name = "Anna"
anna.tel = "23456789"
anna.Person.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
anna.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
}
結論
在同一層面,當然加上匿名指針也可
第4.2組測試
結構中有匿名指針指向另一個結構
測試方法的繼承
但是定義傳指針的method
package main
import "fmt"
type Person struct {
name string
age int
tel string
}
type Student struct {
* Person // 匿名指針指向一個字段
school string
}
//在person上面定義了一個傳指針的method
func (p * Person)
Hello() {
fmt.Printf( "My name is %s, and my tel
number is %s\n", p.name, p.tel)
}
func main() {
anna := new(Student)
anna.Person = new(Person)
anna.Person.name = "Anna"
anna.tel = "34"
anna.Person.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
anna.Hello() // 匿名字段,相當於匿名結構直接嵌入,在同一層面
}
結論:
一樣使用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.