從計算機實現角度來看,變數是一段或多段用來儲存資料的記憶體
go變數總是有固定的資料型別,型別決定了變數記憶體的長度和儲存格式;通過型別轉換或指標操作,我們可用不同方式修改變數值,但這並不意味著改變了變數型別;因為記憶體分配發生在執行期,所以在編碼階段我們用乙個易於閱讀的名字來表示這段記憶體。實際上,編譯後的機器碼從不使用變數名,而是直接通過記憶體位址來訪問目標資料。儲存在符號表中的變數名等資訊可被刪除,或用於輸出更詳細的錯誤資訊
建議以組方式整理多行變數定義
var
簡短模式(:=)定義變數只能用在函式內部
簡短模式並不總是重新定義變數,也可能是部分退化的賦值操作,退化賦值的前提條件是:最少有乙個新變數被定義,且必須是同一定義域;在處理函式錯誤返回值時,退化賦值允許我們重複使用err變數(也要符合上述前提條件)
func
main()
func
main()
}func
main()
在多變數賦值時,首先計算出所有右值,然後再依次完成賦值操作;先計算所有相關值,然後再從左到右依次賦值func
main()
data, i :=[3
]int,0
i, data[i]=2
,100
// (i = 0) -> (i = 2), (data[0] = 100)
編譯器將未使用的區域性變數當做錯誤,全域性變數沒有問題
使用常量就可用乙個易於閱讀理解的識別符號號來代替「魔法數字」,常量值必須是編譯期可確定的字元、字串、數字或布林值
可在函式**塊中定義常量,不曾使用的常量不會引發編譯錯誤
func
main()
}// 輸出:123 abc
在常量組中如不指定型別和初始化值,則與上一行非空常量右值(表示式文字)相同func
main()
go沒有明確意義上的enum定義,不過可借助iota識別符號實現一組自增常量值來實現列舉型別const
( x =
iota
// 0
y // 1
z // 2
)const(_
=iota
// 0
kb =
1<<(10
*iota
)// 1 << (10 * 1)
mb // 1 << (10 * 2)
gb // 1 << (10 * 3)
)
自增作用範圍為常量組。可在多常量定義中使用多個iota,它們各自單獨計數,只須確保組中每行常量的列數量相同即可const(_
,_=iota
,iota*10
// 0, 0 * 10
a, b // 1, 1 * 10
c, d // 2, 2 * 10
)
如果中斷iota自增,必須顯式恢復,且後續自增值按行序遞增,而非c enum那般按上一取值遞增const
( a =
iota
// 0
b // 1
c =100// 100
d // 100(與上一行常量右值表示式相同)
e =iota
// 4(恢復iota自增,計數包括c, d)
f // 5
)
自增預設資料型別為int,可顯式指定型別const
( a =
iota
//int,0
b float64
=iota
//float32,1
c =
iota
//int(如不顯式指定iota,則與b資料型別相同),2
)
不同於變數在執行期分配儲存記憶體(非優化狀態),常量通常會被編譯器在預處理階段直接展開,作為指令資料使用
數字常量不會分配儲存空間,無須像變數那樣通過記憶體定址來取值,因此無法獲取位址
const x =
100// 無型別宣告的常量
const y byte
= x // 直接展開x,相當於const y byte = 100
fmt.
printf
("%p"
,&x)
//編譯錯誤,不可以對x取位址, cannot take the address of x
const a int
=100
// 顯式指定常量型別,編譯器會做強型別檢查
const b byte
= a // 錯誤,cannot use a (type int) as type byte in const initializer
標準庫math定義了各數字型別的取值範圍,math.minint8, math.maxint8
使用浮點數時,須注意小數字的有效精度,注意不要對浮點數使用 ==
別名
// byte alias for uint8
// rune alias for uint32
引用型別特指slice,map,channel三種預定義型別
內建函式new按指定型別長度分配零值記憶體,返回指標,並不關心型別內部構造和初始化方式。而引用型別必須使用make函式建立,編譯器會將make轉換為目標型別專用的建立函式(或指令),以確保完成全部記憶體分配和相關屬性初始化。當然,new函式也可為引用型別分配記憶體,但這是不完整建立。以字典為例,它僅分配了字典型別本身(實際就是個指標包裝)所需記憶體,並沒有分配鍵值儲存記憶體,也沒有初始化雜湊桶等內部屬性,因此它無法正常工作
使用 「`」 定義不做轉義處理的原始字串,支援跨行
s :=
`ab\r\n\x00
c`println
(s)// 輸出:
// a
// b\r\n\x00
// c
unsafe包:
位操作
a :=
0a |=
1<<
2// 0000100: 在 bit2 設定標誌位。
a |=
1<<
6// 1000100: 在 bit6 設定標誌位
a = a &^(1
<<6)
// 0000100: 清除 bit6 標誌位。
go 方法 摘自go語言學習筆記
如何選擇方法的receiver型別 要修改例項狀態,用 t 無須修改狀態的小物件或固定值,建議用t 大物件建議用 t,以減少複製成本 引用型別 字串 函式等指標包裝物件,直接用t 若包含mutex等同步字段,用 t,避免因複製造成鎖操作無效 其他無法確定的情況,都用 t 方法集 型別t方法集包含所有...
Go語言學習筆記 Go語言資料型別
布林型 布林型的值只可以是常量true或者false。乙個簡單的例子 var b bool true。數字型別 整型int和浮點型float32 float64,go 語言支援整型和浮點型數字,並且支援複數,其中位的運算採用補碼。字串型別 字串就是一串固定長度的字元連線起來的字串行。go 的字串是由...
7 1 介面摘自《go語言學習筆記》
1,介面實現機制 只要目標方法集內包含介面宣告的全部方法,就被視為實現了該介面,無需做顯示宣告。目標型別可以實現多個介面。2,內部實現,介面自身也是一種結構型別 type iface struct不能有欄位 不能定義自己的方法。只能宣告方法,不能實現。可嵌入其它介面型別。3,介面通常以er作為介面字...