- 如果我們需要聲明不同類型的變量 那么可以按照以下語法聲明
var (
name1 = initialvalue1
name2 = initialvalue2
)
- :=語法至少要有一個新的變量
package main
import "fmt"
func main() {
a, b := 20, 30 // declare variables a and b
fmt.Println("a is", a, "b is", b)
b, c := 40, 50 // b is already declared but c is new
fmt.Println("b is", b, "c is", c)
b, c = 80, 90 // assign new values to already declared variables b and c
fmt.Println("changed b is", b, "c is", c)
}
如果聲明的變量都不是新的 就會報錯
printf println的區(qū)別
https://blog.csdn.net/zgh0711/article/details/78843361
需要格式化輸出 使用printf 需要輸出字符串 變量 就用println
使用格式化輸出占位符 %T 輸出變量類型
unsafe.sizeOf輸出變量內(nèi)存浮點數(shù) 整數(shù) 聲明不帶位數(shù)的話拓提,默認表示為系統(tǒng)位數(shù)
如果你的系統(tǒng)為32位泛粹,那么float int 默認為float32 int32
64位相同int 代表整數(shù) 包括正整數(shù) 以及負整數(shù) uint 代表正整數(shù)
浮點數(shù)相加相減問題
原因可看此處https://blog.csdn.net/u010897392/article/details/37878155通過T()來強轉(zhuǎn)類型 強轉(zhuǎn)類型必須顯性聲明類型
package main
import "fmt"
func main() {
i := 53
var j float64 = float64(i)
var k string = string(i)
fmt.Println(j, k+"324234")
}
- 常量必須在編譯時已知 不可以被聲明為函數(shù) 因為函數(shù)會在運行時被調(diào)用
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Hello, playground")
var a = math.Sqrt(4)//allowed
const b = math.Sqrt(4)//not allowed
}
- 單個字符串是一個無類型常量(。该押。并沒有太看懂有什么用意筒主。撕捍。。)
const hello = "Hello World"
無類型常量 “hello world” 分配給了 常量 hello 那么這個常量 還是無類型的
雖然是無類型常量 但是如果使用%T(hello) 那么將輸出string 因為無類型常量將在需要時提供一個關(guān)聯(lián)的默認類型 string
- 命名返回值
area and perimeter are the named return values in the above function. Note that the return statement in the function does not explicitly return any value. Since area and perimeter are specified in the function declaration as return values, they are automatically returned from the function when a return statement in encountered.
area 和 perimeter 在上面這個函數(shù)中都是被命名的返回值师脂。注意這個函數(shù)中返回語句并沒有指定任何返回值担孔。從area和perimeter被指定為命名返回值時,函數(shù)就會返回他們吃警,并且會在函數(shù)調(diào)用reutrn時自動返回
ps. 這個特性的用意應(yīng)該是讓人更清晰的理解返回值是什么 直接命名返回值的做法比在代碼中尋找返回值的變量名來理解更加清晰 當(dāng)然這應(yīng)該是注釋的功能之一
// 用意應(yīng)該是注釋的這個功能
/**
* @return { int } area
* @return { int } perimeter
*/
func rectProps(length int, width int) (area int, perimeter int) { // 直觀的理解返回值的意義
area = length * width // 無需聲明變量
perimeter = (length + width) * 2
return // 無需顯式返回
}
- 空白標識符 _
當(dāng)有多個返回值時糕篇, 可以用_來拋棄無用的變量
area3, _ := rectProps(7, 2)
fmt.Println("area %f", area3)
go在windows下的環(huán)境變量配置
go install以及go build命令需要配置好GOBIN以及GOPATH兩個環(huán)境變量 否則將會報錯 找不到GOBIN變量可以聲明在if語句中
if num := 10; num % 2 == 0 { //checks if number is even
fmt.Println(num,"is even")
} else {1. 如果我們需要聲明不同類型的變量 那么可以按照以下語法聲明
``` GO
var (
name1 = initialvalue1
name2 = initialvalue2
)
- :=語法至少要有一個新的變量
package main
import "fmt"
func main() {
a, b := 20, 30 // declare variables a and b
fmt.Println("a is", a, "b is", b)
b, c := 40, 50 // b is already declared but c is new
fmt.Println("b is", b, "c is", c)
b, c = 80, 90 // assign new values to already declared variables b and c
fmt.Println("changed b is", b, "c is", c)
}
如果聲明的變量都不是新的 就會報錯
printf println的區(qū)別
https://blog.csdn.net/zgh0711/article/details/78843361
需要格式化輸出 使用printf 需要輸出字符串 變量 就用println
使用格式化輸出占位符 %T 輸出變量類型
unsafe.sizeOf輸出變量內(nèi)存浮點數(shù) 整數(shù) 聲明不帶位數(shù)的話,默認表示為系統(tǒng)位數(shù)
如果你的系統(tǒng)為32位酌心,那么float int 默認為float32 int32
64位相同int 代表整數(shù) 包括正整數(shù) 以及負整數(shù) uint 代表正整數(shù)
浮點數(shù)相加相減問題
原因可看此處https://blog.csdn.net/u010897392/article/details/37878155通過T()來強轉(zhuǎn)類型 強轉(zhuǎn)類型必須顯性聲明類型
package main
import "fmt"
func main() {
i := 53
var j float64 = float64(i)
var k string = string(i)
fmt.Println(j, k+"324234")
}
- 常量必須在編譯時已知 不可以被聲明為函數(shù) 因為函數(shù)會在運行時被調(diào)用
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Hello, playground")
var a = math.Sqrt(4)//allowed
const b = math.Sqrt(4)//not allowed
}
- 單個字符串是一個無類型常量(拌消。。并沒有太看懂有什么用意安券。墩崩。。)
const hello = "Hello World"
無類型常量 “hello world” 分配給了 常量 hello 那么這個常量 還是無類型的
雖然是無類型常量 但是如果使用%T(hello) 那么將輸出string 因為無類型常量將在需要時提供一個關(guān)聯(lián)的默認類型 string
- 命名返回值
area and perimeter are the named return values in the above function. Note that the return statement in the function does not explicitly return any value. Since area and perimeter are specified in the function declaration as return values, they are automatically returned from the function when a return statement in encountered.
area 和 perimeter 在上面這個函數(shù)中都是被命名的返回值侯勉。注意這個函數(shù)中返回語句并沒有指定任何返回值鹦筹。從area和perimeter被指定為命名返回值時,函數(shù)就會返回他們址貌,并且會在函數(shù)調(diào)用reutrn時自動返回
ps. 這個特性的用意應(yīng)該是讓人更清晰的理解返回值是什么 直接命名返回值的做法比在代碼中尋找返回值的變量名來理解更加清晰 當(dāng)然這應(yīng)該是注釋的功能之一
// 用意應(yīng)該是注釋的這個功能
/**
* @return { int } area
* @return { int } perimeter
*/
func rectProps(length int, width int) (area int, perimeter int) { // 直觀的理解返回值的意義
area = length * width // 無需聲明變量
perimeter = (length + width) * 2
return // 無需顯式返回
}
- 空白標識符 _
當(dāng)有多個返回值時铐拐, 可以用_來拋棄無用的變量
area3, _ := rectProps(7, 2)
fmt.Println("area %f", area3)
go在windows下的環(huán)境變量配置
go install以及go build命令需要配置好GOBIN以及GOPATH兩個環(huán)境變量 否則將會報錯 找不到GOBIN變量可以聲明在if語句中
if num := 10; num % 2 == 0 { //checks if number is even
fmt.Println(num,"is even")
} else {
fmt.Println(num,"is odd")
}
fmt.Printf("num = %f", num) // error!
但是作用域盡在if語句中
好奇怪的寫法
- else 語句必須在if語句結(jié)束的花括弧同一行练对, 如果在下一行 就會報錯
if num := 10; num % 2 == 0 { //checks if number is even
fmt.Println(num,"is even")
}
else {
fmt.Println(num,"is odd")
} // not work!
這是因為GO會自動添加分號
- GO只有for循環(huán)
- break用來停止循環(huán) continue用來跳過本次代碼塊的執(zhí)行
- break label 用于跳出循環(huán)遍蟋。
- for循環(huán)的3個組成部分都是可選的
18.fallthrough 語句將會讓switch語句中成功執(zhí)行的case轉(zhuǎn)移到下一個case 語句
19 go中的數(shù)組拷貝都是淺拷貝 也就是說改變拷貝的值不影響原值 將數(shù)組作為參數(shù)也是一樣
fmt.Println(num,"is odd")
}
fmt.Printf("num = %f", num) // error!
但是作用域盡在if語句中
好奇怪的寫法
- else 語句必須在if語句結(jié)束的花括弧同一行螟凭, 如果在下一行 就會報錯
if num := 10; num % 2 == 0 { //checks if number is even
fmt.Println(num,"is even")
}
else {
fmt.Println(num,"is odd")
} // not work!
這是因為GO會自動添加分號
- GO只有for循環(huán)
- break用來停止循環(huán) continue用來跳過本次代碼塊的執(zhí)行
- break label 用于跳出循環(huán)虚青。
- for循環(huán)的3個組成部分都是可選的
18.fallthrough 語句將會讓switch語句中成功執(zhí)行的case轉(zhuǎn)移到下一個case 語句 - GO中的數(shù)組都是淺拷貝 也就是說改變拷貝的值不影響原值
package main
import (
"fmt"
)
func main () {
nums := [3]int{5, 7, 2}
nums1 := nums
nums1[0] = 7
fmt.Println(nums) // [5, 7, 2] // 修改拷貝的值不影響原值
fmt.Println(nums1) // [7, 7, 2]
}
- GO中的slice屬于引用,改變slice將會影響原來的Array 并且可能影響其他的slice
nums2 = nums[0:2] // 請注意 slice是[start : end] start是下標 end是index - 1
fmt.Println(nums2) // [5, 7]
nums2[1] = 3
fmt.Println(nums2) // [5, 3]
fmt.Println(nums) // [5, 3, 2]
- GO中的slice擁有數(shù)量和容量的概念
數(shù)量指的是slice的節(jié)點數(shù)量
容量值得是slice所引用數(shù)組的下標數(shù)
fruitArray := [...]string{"23213", "dsfdsf", "dsfrwg", "fregreg", "rgtrjrrhtr"}
fruitSlice := fruitArray[1, 5]
fmt.Println(fruitSlice) // ["dsfdsf", "dsfrwg", "fregreg", "rgtrjrrhtr"]
fmt.Println(len(fruitSlice), cap(fruitSlice)) // 4, 4
slice append 插入原來的切片將返回一個新的數(shù)組以及新的切片
對于一個容量和數(shù)量都為0的切片螺男,被稱為
nil
nil可以使用append函數(shù)來填充內(nèi)容
var names []string // 聲明
if names == nill {
names = append(names, "chen yu", "scscs", "cssss")
}
fmt.Println(names, len(names), cap(names)) // ["chen yu" "scscs" "cssss"] 3, 3
- 對于多個切片棒厘,你可以用append結(jié)合
...
操作符來合并多個切片
veggies := []string{"potatoes", "tomatoes", "brinjal"}
fruits := []string{"oranges", "apples"}
food := append(veggies, fruits...)
fmt.Println(food) // [potatoes tomatoes brinjal oranges apples]
- slice和array的區(qū)別
numbers := [5]int // 數(shù)組
numbers1 := []int // 切片
不指定數(shù)量的是切片
切片是引用傳遞
數(shù)組是副本
函數(shù)傳參數(shù)組是副本傳遞
函數(shù)傳參切片是引用傳遞
- 變量參數(shù) 對于 切片參數(shù)的優(yōu)勢
- 理解可變參數(shù)以及切片 引用和拷貝的區(qū)別
package main
import (
"fmt"
)
func change(s ...string) {
s[0] = "Go"
s = append(s, "playground")
fmt.Println(s)
}
func main() {
welcome := []string{"hello", "world"}
change(welcome...)
fmt.Println(welcome)
}
上面的操作中,welcome最終結(jié)果是[GO world] 原因是 append函數(shù)將會創(chuàng)建一個新的splice 以及其引用的array append函數(shù)會拷貝原變量 而不是引用它 而slice參數(shù)傳遞是引用傳遞 所以改變s參數(shù)下標的值 會改變傳入的welcome變量
- Map類型 如果獲取的key不存在下隧,那么value會返回0
amap := map[string]int {
"qwd": 1
"fd": 45
"grg": 466
}
fmt.Println(amap['ffdfff']) // 0
- 如果不確定key是否存在與map
map[key]會返回兩個參數(shù)
value, ok := map[key]
fmt.Println(value, ok) // 0 false
map和slice一樣 也是引用類型
除非map是nil 否則不可以做比較操作
==
指針的類型聲明是*T 比如
a := *int
&操作符用來獲取內(nèi)存地址
b := 255
a = &b
fmt.Println(a) // 0xc000012090
- interface是一組函數(shù)簽名
type MyInterface interface{
Print()
} // 定義一個擁有Print函數(shù)的interface
func TestFunc(x MyInterface) {}// TestFunc的參數(shù)必須是MyInterface類型的 也就是必須擁有Print函數(shù)的對象
type MyStruct struct {} // 聲明一個數(shù)據(jù)結(jié)構(gòu)
func (me MyStruct) Print() {} // 聲明一個基于MyStruct結(jié)構(gòu)的Print函數(shù)
func main() {
var me MyStruct // 初始化一個MyStruct類型的變量
TestFunc(me) // 將這個變量傳參進去绊谭,由于MyStruct類型擁有Print函數(shù) 所以這段代碼正確執(zhí)行
}
``'
34.函數(shù)傳參都是拷貝傳參 除了splice map channel是指針傳遞 可以用指針來進行值傳參
'''
package main
import "fmt"
//簡單的一個函數(shù),實現(xiàn)了參數(shù)+1的操作
func add1(a int) int {
a = a+1 // 我們改變了a的值
return a //返回一個新值
}
func main() {
x := 3
fmt.Println("x = ", x) // 應(yīng)該輸出 "x = 3"
x1 := add1(x) //調(diào)用add1(x)
fmt.Println("x+1 = ", x1) // 應(yīng)該輸出"x+1 = 4"
fmt.Println("x = ", x) // 應(yīng)該輸出"x = 3"
}
'''