### 匿名字段
一般情況下,定義結構體的時候是字段名與其他類型一一對應,實際上go支持只提供類型,而不寫字段名的
方式,也就是匿名字段,也稱為嵌入字段 .當匿名字段也是一個結構體的時候,那么這個結構體所擁有的全
部字段都被隱式的引入了當前定義的這個結構體 .
#### 賦值
**注意 : 賦值的時候要么只寫值,如果有一個字段寫了字段名,那么所有的字段都要寫字段名**.
~~~
type Person struct {
name string
gender byte
age int
}
type Student struct {
Person //只有類型,沒有名字,繼承了Person的成員
id int
addr string
}
func main() {
var s1 Student
s1.Person.name = "jack"
s1.Person.gender = '1'
s1.Person.age = 20
s1.id = 1
s1.addr = "杭州"
fmt.Println(s1)
//自動推導類型
s2 := Student{Person{"米蘭", '0', 22}, 2, "北京"}
fmt.Printf("%+v\n", s2) //%+v 顯示更詳細
//指定成員初始化,沒有初始化的為零值
s3 := Student{id: 4, addr: "上海"}
fmt.Printf("%+v\n", s3)
s4 := Student{Person: Person{name: "mike"}, id: 3}
fmt.Printf("%+v", s4)
}
~~~
~~~
{{jack 49 20} 1 杭州}
{Person:{name:米蘭 gender:48 age:22} id:2 addr:北京}
{Person:{name: gender:0 age:0} id:4 addr:上海}
{Person:{name:mike gender:0 age:0} id:3 addr:}
~~~
#### 成員操作
~~~
s1 := Student{Person{"jack", 1, 20}, 1, "杭州"}
fmt.Printf("%+v\n", s1)
s1.id = 2
s1.Person.name = "mike"
fmt.Printf("%+v\n", s1)
s1.Person = Person{"milan",0,18}
fmt.Printf("%+v\n", s1)
~~~
#### 同名字段
就近原則,如果能在本作用域找到此成員,就操作此成員,如果找不到,就找繼承的字段.
~~~
s1 := Student{Person{"jack",1,18},1,"milan","杭州"}
fmt.Printf("%+v\n",s1)
~~~
~~~
{Person:{name:jack gender:1 age:18} id:1 name:milan addr:杭州}
~~~
改為如下:
~~~
type Person struct {
name string
gender byte
age int
}
type Student struct {
Person
id int
//name string //這里注釋掉了
addr string
}
func main() {
var s1 Student
s1.name = "jack"
fmt.Printf("%+v", s1)
}
~~~
~~~
{Person:{name:jack gender:0 age:0} id:0 addr:} //直接賦值到了繼承的類型中的name上去了
~~~
#### 非結構體匿名字段
~~~
type myString string
type Person struct {
name string
gender byte
age int
}
type Student struct {
Person
int
myString
}
func main() {
s := Student{Person{"jack", 0, 18}, 666, "hello world"}
fmt.Printf("%+v\n", s)
fmt.Println(s.name, s.age, s.Person, s.int, s.myString)
}
~~~
~~~
{Person:{name:jack gender:0 age:18} int:666 myString:hello world}
jack 18 {jack 0 18} 666 hello world
~~~
### 結構體指針類型匿名字段
~~~
type myString string
type Person struct {
name string
gender byte
age int
}
type Student struct {
*Person
int
myString
}
func change(s Student) {
s.Person.name = "米蘭"
s.int = 1000
}
func main() {
s := Student{&Person{"jack", 0, 18}, 666, "hello world"}
fmt.Printf("%+v\n", s)
fmt.Println(s.name, s.age, s.Person, s.int, s.myString)
change(s)
fmt.Println(s.Person, s.int)
//兩種方式
var s2 Student
s2.Person = new(Person) //分配空間
s2.Person.name = "milan"
fmt.Println(s2)
}
~~~
~~~
{Person:0xc42000a060 int:666 myString:hello world}
jack 18 &{jack 0 18} 666 hello world
&{米蘭 0 18} 666
{0xc42000a0e0 0 }
~~~
- 基本語法
- 申明變量
- 常量
- 數據類型
- 強制類型轉換
- 獲取命令行參數
- 指針
- 概述
- new函數
- 函數
- 概述
- 不定參數類型
- 有返回值
- 函數類型
- 回調函數
- 匿名函數和閉包
- 延遲調用defer
- 工程管理
- 工作區
- src,pkg和bin目錄
- 復合類型
- 概述
- 數組
- 概述
- 聲明并初始化
- 拷貝傳值
- slice
- 概述
- 創建切片
- 切片截取
- 切片和底層數組的關系
- slice常用方法
- 切片做函數參數
- map
- 概述
- map操作
- 結構體
- 概述
- 結構體初始化
- 結構體比較
- 結構體作為函數參數
- 結構體前加&
- 面向對象
- 概述
- 匿名組合
- 方法
- 值語義和引用語義
- 方法集
- 方法的繼承
- 方法重寫
- 方法值
- 接口
- 接口定義和實現
- 多態的表現
- 接口繼承
- 接口轉換
- 空接口
- 類型斷言
- 異常處理
- error接口
- panic
- recover
- 文本文件處理
- 字符串操作
- 正則表達式
- json處理
- 文件操作
- 標準設備文件操作
- 并發編程
- 概述
- 并發和并行
- go語言并發優勢
- goroutine
- goroutine概述
- 創建goroutine
- 主協程先退出
- runtime包
- Gosched
- Goexit
- GOMAXPROCE
- channel
- 多資源競爭
- channel類型
- 無緩沖channel
- 有緩沖channel
- 關閉channel
- 單向channel
- 單向channel特性
- 定時器
- Timer
- Ticker
- select
- select作用
- 超時
- sync
- 競爭狀態
- 網絡編程
- 網絡概述
- 網絡協議
- 分層模型
- 網絡分層架構
- 層與協議
- 每層協議的功能
- 鏈路層
- 網絡層
- 傳輸層
- 應用層
- socket編程
- 組合和繼承
- 注意事項
- 細節
- go語言實現隊列
- google工程師golang
- 基礎語法
- 內建容器
- 面向"對象"
- 依賴管理
- 面向接口
- 函數式編程
- 錯誤處理和資源管理
- 測試與性能調優
- goroutine
- channel
- golang問題集
- 斷言和類型轉換
- Go語言圣經
- 入門
- 程序結構
- 命名
- 聲明
- 變量
- 賦值
- 類型
- 包和文件
- 作用域
- 基礎數據類型
- 整數
- 浮點數
- 復數
- 布爾型
- 字符串
- 常量
- 復合數據類型
- 數組
- slice
- map
- 結構體
- json
- 文本和HTML模板
- 函數
- 函數聲明
- 錯誤
- 函數值
- 匿名函數
- defer
- panic
- recover
- 方法
- 方法聲明
- 指針對象的方法
- 封裝
- 接口
- 說明
- 接口是合約
- 實現接口的條件
- 接口值
- 類型斷言
- 通過類型斷言詢問行為
- 類型開關
- Goroutines和Channels
- 協程
- channels
- 無緩沖channel
- 串聯的channel
- 有緩沖channel
- 并發的循環
- select多路復用
- 并發的退出
- 并發問題的自我思考
- 基于共享變量的并發
- 競爭條件
- 互斥鎖
- 讀寫鎖
- 內存同步
- sync.Once
- 協程和線程
- 包和工具
- 測試
- 反射
- 什么是反射
- 為什么需要反射
- reflect.Type和reflect.Value
- 通過reflect.Value修改值
- 底層編程