在 Go 程序中,一行表明一個語句結束。每一個語句不須要像 C 家族中的其它語言同樣以分號 ; 結尾,golang
可是可使用分號;結尾,若是當你將多個語句寫在同一行時,則必須使用分號;數據庫
功能:存儲用戶的數據編程
注意: 變量必須通過聲明才能開始使用數組
標準格式:數據結構
var 變量名 變量類型
變量的聲明以關鍵字 var 開頭,行尾不須要寫分號編程語言
package main import ( "fmt" ) func main() { var a int var b string var c []float32 var d func () bool var e struct { x int } }
代碼說明:ide
第3行,聲明一個整型類型的變量,能夠保存整數數值。函數
第4行,聲明一個字符串類型的變量。post
第5行,聲明一個 32 位浮點切片類型的變量,浮點切片表示由多個浮點類型組成的數據結構。學習
第6行,聲明一個返回值爲布爾類型的函數變量,這種形式通常用於回調函數,即將函數以變量的形式保存下來,在須要的時候從新調用這個函數。
第7行,聲明一個結構體類型的變量,這個結構體擁有一個整型的 x 字段。
使用var關鍵字和括號批量聲明(推薦)
var ( a int b string c []float32 d func () bool e struct { x int } )
使用關鍵字var和括號,能夠將一組變量定義放在一塊兒。
變量的聲明能夠包含初始值,每個變量對應一個值。
若是初始化值已存在,則能夠省略類型;變量會從初始值中得到類型。
變量初始化的標準格式:
var 變量名 類型 = 表達式
簡化形式:
var 變量名 = 表達式
例如:
var x int = 100
能夠寫成:
var x = 100
默認值:
沒有明確初始值的變量聲明會被賦予它們一個默認值:
整型和浮點型變量的默認值爲 0。 字符串變量的默認值爲空字符串。 布爾型變量默認爲 bool。 切片、函數、指針變量的默認爲 nil。
注意:變量已經被聲明過了,再次聲明並賦值,使用短變量聲明會編譯報錯
var p string p := '123' fmt.Println(p) // 錯誤信息:no new variables on left side of :=(44.4) // var p 聲明瞭p變量, p := '123' 會再次聲明並賦值
注意:因爲使用了 :=
,而不是賦值的 =
,所以推導聲明寫法的左值變量必須是沒有定義過的變量。若定義過,將會發生編譯錯誤。
注意:在多個短變量聲明和賦值中,至少有一個新聲明的變量出如今左值中,即使其餘變量名多是重複聲明的,編譯器也不會報錯,例如:
x, z := a, b y, z := a, b
使用Go的「多重賦值特性」,能夠輕鬆完成變量交換的任務。
package` `main import` `"fmt"
func main() { var a = 100 var b = 200 a, b = b, ago fmt.Println(a, b) }
多重賦值時,變量的左值和右值按從左到右的順序賦值。
在使用多重賦值時,若是不須要在左值中接收變量,可使用匿名變量。
匿名變量用一個下劃線 _ 來表示
,使用匿名變量時,只須要在變量聲明的地方使用下劃線替換便可。例如:
var a int a, _ = 100, 200
注意:匿名變量不佔用命名空間,不會分配內存。匿名變量與匿名變量之間也不會由於屢次聲明而沒法使用。
package main import ("fmt") func main() { a1, _ := getData() _, b1 := getData() fmt.Println(a1, b1) } type IntSlice []int // 編寫一個len方法,提供切片的長度 func (p IntSlice) Len() int { return len(p)} // 根據提供i,j元素索引,兩個元素進行比較,返回比較結果 func (p IntSlice) Less(i, j int) bool { return p[i] < p[j]} // 根據提供i,j元素索引,交換兩個元素的值 func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i]} func getData() (int, int) { return 200, 100 }
常量是恆定不變的值,例如圓周率。
常量的聲明與變量相似,只不過是使用 const 關鍵字。
常量能夠是字符、字符串、布爾值和數值。
常量不能用 := 語法聲明。
常量的聲明, 例如:
const pi = 3.1415926
注意:常量在聲明的時候必須賦值。
多個變量能夠一塊兒聲明,相似的,多個變量也能夠一塊兒聲明。例如:
const( pi = 3.1415926 e = 2.718281 )
Go語言中有豐富的數據類型,除了基本的整型、浮點型、布爾型、字符串外,還有切片、結構體、函數、map、通道(channel)等。
Go 語言的基本類型和其餘語言大同小異。
整型能夠分紅如下兩個大類:
按長度分爲:int八、int1六、int3二、int64
對應的無符號整型:uint八、uint1六、uint3二、uint64
其中,uint8 就是咱們熟知的 byte 型.
Go語言支持兩種浮點型數:
float3二、float64.
注意:沒有float
Go語言的浮點型默認聲明爲float64.
布爾型數據只有 true(真)和 false(假)兩個值。
注意:
在Go語言中, true和false均爲小寫 不容許將整型強制轉換爲布爾型
字符串的兩種表示形式:
\1. 雙引號,會識別轉義字符
\2. 反引號,不會識別轉義字符。以字符串的原生形式輸出,包括換行和特殊字符。
轉義符 | 含義 |
---|---|
\r | 回車符(返回行首) |
\n | 換行符 |
\t | 製表符 |
' | 單引號 |
" | 雙引號 |
\ | 反斜槓 |
const str = ` 第一行 第二行 第三行 \r\n` fmt.Println(str)
代碼運行結果:
第一行 第二行 第三行 \r\n
字符串中的每個元素叫作「字符」,在遍歷或者單個獲取字符串元素時能夠得到字符。
Go語言的字符有如下兩種:
Go語言使用類型前置加括號的方式進行類型轉換,通常格式以下:
T(表達式)
其中,T 表明要轉換的類型。表達式包括變量、複雜算子和函數返回值等。
注意:在類型轉換時,須要考慮兩種類型的關係和範圍,是否會發生數值截斷等。
package main import "fmt" func main(){ var n1 int = 20 var n2 float64 = float64(n1) n2 = n2 + 3.6 var n3 int32 = int32(n2) // 當將一個float類型轉成 int時,是直接去掉小數點後的部分 fmt.Printf("n1 type=%T, val=%v; n2 type=%T, val=%v; n3 type=%T, val=%v\n", n1, n1, n2, n2, n3, n3) }
代碼運行結果:
n1 type=int, val=20; n2 type=float64, val=23.6; n3 type=int32, val=23
兩個核心:
一種是類型指針
,容許對這個指針類型的數據進行修改。 傳遞數據使用使用指針,而無須拷貝數據 類型指針不能進行偏移和運算
二種是切片
, 由指向起始元素的原始指針、元素數量和容量組成
每一個變量在運行時都會被內存分配一個地址,這個地址表明變量在內存中的位置 使用「&」操做符放在變量前面對變量進行「取地址」操做 格式:
ptr := &variable //variable的類型爲T
其中v表明被取地址的變量,被取地址的variable使用ptr變量進行接收,ptr的類型爲「T」,稱做T的指針類型。「」表明指針
package main import ( "fmt" "math" ) func main() { var cat int = 1 var str2 string = "banana" fmt.Printf("%p, %p\n", &cat, &str2) } //0xc00004e0e8, 0xc0000421f0 爲cat,str2取地址後的指針值
注意:變量、指針和地址三種的關係是:每一個變量都擁有地址,指針的值就是地址
對變量「&」取地址操做後得到這個變量的指針,對指針使用「*」操做,就是指針取值
package main import ( "fmt" "math" ) func main() { var house = "Malibu Point 10880, 90265" // 對字符串取地址,ptr1類型爲*string ptr1 := &house // 打印ptr類型 fmt.Printf("ptr1 類型:%T\n", ptr1) // 打印ptr指針地址 fmt.Printf("ptr1 地址:%p\n", ptr1) // 對指針進行取值操做 value := *ptr1 // 取值後類型 fmt.Printf("value 類型:%T\n", value) // value值 fmt.Printf("value:%s\n", value) } // ptr1 類型:*string // ptr1 地址:0xc000042200 // value 類型:string // value:Malibu Point 10880, 90265
總結:
取地址「&」和取值「」是一對互補操做符,「&」取地址,"&"根據地址取出地址指向的值
1.對變量進行其地址(&)操做,可得到這個變量的指針變量
2.指針變量的值是指針地址
3.對指針變量進行取值()操做,能夠得到指針變量指向的原變量的值
x, y := 1,2
package main import ( "fmt" "math" ) func main() { //錯誤示例 swap1(&x, &y) fmt.Println("x: ",x, "y:", y) //x: 1 y: 2 //正確 swap(&x, &y) fmt.Println("x: ", x, "y: ",y) //x: 2 y: 1 } // 交換函數 func swap(a, b *int) { // 取a的指針的值,賦給臨時變量t t := *a //取b指針的值,賦值給a指針指向的變量 *a = *b //a指針的值賦值給b指針指向的變量 *b = t } // 錯誤示例 func swap1(a, b *int) { b, a = a, b }
new(類型)
str3 := new(string) *str3 = "ninja" fmt.Println(*str3) fmt.Println(str3) //ninja //0xc000042230
go 語言字符串都是以UTF-8格式保存,每一箇中文佔用3個字符
tip1 := "genji is a ninja" fmt.Println(len(tip1)) // 16 tip2 := "忍者無敵" fmt.Println(len(tip2)) //12 // 使用RuneCountInString()統計Uncode字符數量 fmt.Println(utf8.RuneCountInString("忍者"))
總結
兩種寫法
theme := "阻擊 start" for i := 0; i < len(theme); i++ { fmt.Printf("ascii: %c %d\n", theme[i], theme[i]) } // ascii: é 233 // ascii: • 152 // ascii: » 187 // ascii: å 229 // ascii: • 135 // ascii: » 187 // ascii: 32 // ascii: s 115 // ascii: t 116 // ascii: a 97 // ascii: r 114
for _, s := range theme { fmt.Printf("Unicode %c %d\n", s, s) } // Unicode 阻 38459 // Unicode 擊 20987 // Unicode 32 // Unicode s 115 // Unicode t 116 // Unicode a 97 // Unicode r 114 // Unicode t 116
總結:
string.Index() 在字符串中搜索另外一個子串
tracer := "努力擁抱每一天,不斷成長" comma := strings.Index(tracer, "每一天") posi := strings.Index(tracer[comma:], "成長") fmt.Println(comma, posi, tracer[comma+posi:]) // 12 18 成長
總結:
搜索的起始位置能夠經過切片偏移製做
go語言沒法直接修改每個字符元素,只能經過從新構造新的字符串並賦值給原來的字符串變量
angel := "Hero nerver die" arrayBytes := []byte(angel) for i := 5; i <= 10; i++ { arrayBytes[i] = '-' } fmt.Println(arrayBytes) // [72 101 114 111 32 45 45 45 45 45 45 32 100 105 101] fmt.Println(string(arrayBytes)) // Hero ------ die
總結
可使用加號「+」鏈接 可使用相似於StringBuilder的機制鏈接,更高效
hamer := "GO GO GO" sickle := "You Can" // 聲明字節緩衝 var stringBuilder bytes.Buffer // 將字符串寫入緩衝區 stringBuilder.WriteString(hamer) stringBuilder.WriteString(sickle) //將緩衝以字符串形式輸出 fmt.Println(stringBuilder.String()) // GO GO GOYou Can
寫法: fmt.Sprintf(格式化樣式,參數列表)
格式化樣式:字符串形式,格式化動詞以%開頭
參數列表:多個參數以逗號分隔,個數必須與格式化中樣式個數一一對應
var progress = 2 var target = 8 // 兩參數格式化 title := fmt.Sprintf("以完成%d個任務,還差%d個就完成", progress, target) fmt.Println(title) // 以完成2個任務,還差8個就完成 pi := math.Pi // 按數值自己格式輸出 variant := fmt.Sprintf("%v %v %v", "月球基地", pi, true) fmt.Println(variant) // 月球基地 3.141592653589793 true profile := &struct { Name string HP int }{ Name: "stat", HP: 150, } fmt.Printf("使用'%%+v' %+v\n", profile) fmt.Printf("使用'%%#v' %#v\n", profile) fmt.Printf("使用'%%T' %T\n", profile) // 使用'%+v' &{Name:stat HP:150} // 使用'%#v' &struct { Name string; HP int }{Name:"stat", HP:150} // 使用'%T' *struct { Name string; HP int }
base64編碼解碼示例
package main import ( "fmt" "encoding/base64" ) func main() { // 須要處理的字符串 message := "Away from keyboard. https://golang.org/" // 編碼消息, 傳入的字符串需轉爲字節數組,才能供這個函數使用 encodeMessage := base64.StdEncoding.EncodeToString([]byte(message)) // 輸出編碼完成的消息 fmt.Println(encodeMessage) // 解碼消息 data, err := base64.StdEncoding.DecodeString(encodeMessage) // 出錯處理 if err != nil { fmt.Println(err) } else { fmt.Println(string(data)) } // QXdheSBmcm9tIGtleWJvYXJkLiBodHRwczovL2dvbGFuZy5vcmcv // Away from keyboard. https://golang.org/ }
// 使用iota模擬枚舉 type Weapon int const ( Arrow Weapon = iota // 開始生成枚舉值,默認爲0 Shuriken SniperRifle Rifle Blower ) // 輸出全部枚舉值 fmt.Println(Arrow, Shuriken, SniperRifle, Rifle, Blower) var weapon Weapon = Blower fmt.Println(weapon) // 0 1 2 3 4 // 4
package main import ("fmt") // 聲明芯片類型 type ChipType int const ( None ChipType = iota GPU CPU ) func (c ChipType) String() string { switch c { case None: return "None" case GPU: return "GPU" case CPU: return "CPU" } return "N/A" } func main() { // 輸出CPU的值並以整型格式顯示 fmt.Printf("%s %d", CPU, CPU) //CPU 2 }
類型別名的寫法:
type TypeAlias = Type
類型別名規定:
TypeAlias只是Type的別名,本質上TypeAlias與Type是同一個類型
// 將NewInt定義爲int類型 type NewInt int // 將int取一個別名叫IntAlias type IntAlias = int // 將a聲明爲一個NewInt類型 var alias_a NewInt fmt.Printf("a type: %T\n", alias_a) // a type: main.NewInt // 將a2聲明爲IntAlias類型 var alias_a2 IntAlias fmt.Printf("a2 type: %T\n", alias_a2) // a2 type: int
不能爲不在同一個包中聲明的類型定義方法,即不能爲在其餘包聲明的類型在本地包中定義方法
package main import ("time") // 2.8.2 // 定義time.Duration 的別名爲MyDuration type MyDuration = time.Duration // 爲MyDuration 添加一個函數 func (m MyDuration) EasySet(a String) { } func main() { } //# 2-base/2.2-data_type //.\data_type.go:51:6: cannot define new methods on non-local type time.Duration //.\data_type.go:51:31: undefined: String //exit status 2 //Process exiting with code: 1
package main import ( "fmt" "reflect" ) // 定義商標結構 type Brand struct { } // 爲商標結構添加Show()方法 func (t Brand) Show() { } // 爲Brand定義一個別名 type FakeBrand = Brand // 定義車輛結構,嵌入商標結構 type Vehicle struct { Brand FakeBrand } func main() { // 聲明變量 a 爲車輛類型 var a Vehicle // 指定調用FakeBrand的Show a.FakeBrand.Show() // 取a的類型反射對象 ta := reflect.TypeOf(a) // 遍歷a的全部成員 for i := 0; i < ta.NumField(); i++ { // ta 成員信息 f := ta.Field(i) // 打印成員的字段名和類型 fmt.Printf("FieldName: %v, FieldType: %v\n", f.Name, f.Type.Name()) } // FieldName: Brand, FieldType: Brand // FieldName: FakeBrand, FieldType: Brand go }
總結:
if 語句由布爾表達式後緊跟一個或多個語句組成。
Go 編程語言中 if 語句的語法以下:
if 布爾表達式 { /* 在布爾表達式爲 true 時執行 */ }
注意:if語句必定要加{}
if 語句 後可使用可選的 else 語句, else 語句中的表達式在布爾表達式爲 false 時執行。
Go 編程語言中 if...else 語句的語法以下:
if 布爾表達式 { /* 在布爾表達式爲 true 時執行 */ } else { /* 在布爾表達式爲 false 時執行 */ }
注意:每個 if else 都須要加入括號 同時 else 位置不能在新一行
尋找到 100 之內的全部的素數:
package main import "fmt" func main(){ // var count,c int //定義變量不使用也會報錯 var count int var flag bool count=1 //while(count<100) { //go沒有while for count < 100 { count++ flag = true; //注意tmp變量 := for tmp:=2;tmp<count;tmp++ { if count%tmp==0{ flag = false } } // 每個 if else 都須要加入括號 同時 else 位置不能在新一行 if flag == true { fmt.Println(count,"素數") }else{ continue } } }
普通的switch語句:
var i = 0 switch i { case 0: case 1: fmt.Println(「1」) case 2: fmt.Println(「2」) default: fmt.Println(「def」) }
fallthrough語句:
var i = 0 switch i { case 0: fallthrough case 1: fmt.Println(「1」) case 2: fmt.Println(「2」) default: fmt.Println(「def」) }
注:加了fallthrough後,會直接運行【緊跟的後一個】case或default語句,不論條件是否知足都會執行,後面的條件並不會再判斷了。
注意:Go 沒有三目運算符,因此不支持*?: 形式的條件判斷。
for 循環是一個循環控制結構,能夠執行指定次數的循環。
Go 語言的 For 循環有 3 種形式,只有其中的一種使用分號。
和 C 語言的 for 同樣:
for init; condition; post { }
和 C 的 while 同樣:
for condition { }
和 C 的 for(;😉 同樣:
for { }
for語句執行過程以下:
for 循環的 range 格式能夠對 slice、map、數組、字符串等進行迭代循環。格式以下:
for key, value := range oldMap { newMap[key] = value }
計算 1 到 10 的數字之和:
package main import "fmt" func main() { sum := 0 for i := 0; i <= 10; i++ { sum += i } fmt.Println(sum) }
輸出結果爲:
55
init 和 post 參數是可選的,咱們能夠直接省略它,相似 While 語句。
如下實例在 sum 小於 10 的時候計算 sum 自相加後的值:
package main import "fmt" func main() { sum := 1 for ; sum <= 10; { sum += sum } fmt.Println(sum) // 這樣寫也能夠,更像 While 語句形式 for sum <= 10{ sum += sum } fmt.Println(sum) }
輸出結果爲:
16 16
無限循環:
package main import "fmt" func main() { sum := 0 for { sum++ // 無限循環下去 } fmt.Println(sum) // 沒法輸出 }
要中止無限循環,能夠在命令窗口按下ctrl-c 。
For-each range 循環
這種格式的循環能夠對字符串、數組、切片等進行迭代輸出元素。
package main import "fmt" func main() { strings := []string{"google", "runoob"} for i, s := range strings { fmt.Println(i, s) } numbers := [6]int{1, 2, 3, 5} for i,x:= range numbers { fmt.Printf("第 %d 位 x 的值 = %d\n", i,x) } }
以上實例運行輸出結果爲:
0 google 1 runoob 第 0 位 x 的值 = 1 第 1 位 x 的值 = 2 第 2 位 x 的值 = 3 第 3 位 x 的值 = 5 第 4 位 x 的值 = 0 第 5 位 x 的值 = 0
Go 語言數組聲明須要指定元素類型及元素個數,語法格式以下:
var variable_name [SIZE] variable_type
以上爲一維數組的定義方式。例如如下定義了數組 balance 長度爲 10 類型爲 float32:
var balance [10] float32
如下演示了數組初始化:
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
初始化數組中 {} 中的元素個數不能大於 [] 中的數字。
若是忽略 [] 中的數字不設置數組大小,Go 語言會根據元素的個數來設置數組的大小:
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
該實例與上面的實例是同樣的,雖然沒有設置數組的大小。
balance[4] = 50.0
以上實例讀取了第五個元素。數組元素能夠經過索引(位置)來讀取(或者修改),索引從0開始,第一個元素索引爲 0,第二個索引爲 1,以此類推。
數組元素能夠經過索引(位置)來讀取。格式爲數組名後加中括號,中括號中爲索引的值。例如:
var salary float32 = balance[9]
Go 語言支持多維數組,如下爲經常使用的多維數組聲明方式:
var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
如下實例聲明瞭三維的整型數組:
var threedim [5][10][4]int
多維數組可經過大括號來初始值。如下實例爲一個 3 行 4 列的二維數組:
a = [3][4]int{ {0, 1, 2, 3} , /* 第一行索引爲 0 */ {4, 5, 6, 7} , /* 第二行索引爲 1 */ {8, 9, 10, 11}, /* 第三行索引爲 2 */ }
注意:以上代碼中倒數第二行的 } 必需要有逗號,由於最後一行的 } 不能單獨一行,也能夠寫成這樣:
a = [3][4]int{ {0, 1, 2, 3} , /* 第一行索引爲 0 */ {4, 5, 6, 7} , /* 第二行索引爲 1 */ {8, 9, 10, 11}} /* 第三行索引爲 2 */
多維數組經過指定座標來訪問。如數組中的行索引與列索引,例如:
val := a[2][3] 或 var value int = a[2][3]
以上實例訪問了二維數組 val 第三行的第四個元素。
函數是基本的代碼塊,用於執行一個任務。
Go 語言最少有個 main() 函數。
你能夠經過函數來劃分不一樣功能,邏輯上每一個函數執行的是指定的任務。
函數聲明告訴了編譯器函數的名稱,返回類型,和參數。
Go 語言標準庫提供了多種可動用的內置的函數。例如,len() 函數能夠接受不一樣類型參數並返回該類型的長度。若是咱們傳入的是字符串則返回字符串的長度,若是傳入的是數組,則返回數組中包含的元素個數。
Go 語言函數定義格式以下:
func function_name( [parameter list] ) [return_types] { 函數體 }
函數定義解析:
func:函數由 func 開始聲明
function_name:函數名稱,函數名和參數列表一塊兒構成了函數簽名。
parameter list:參數列表,參數就像一個佔位符,當函數被調用時,你能夠將值傳遞給參數,這個值被稱爲實際參數。參數列表指定的是參數類型、順序、及參數個數。參數是可選的,也就是說函數也能夠不包含參數。
return_types:返回類型,函數返回一列值。return_types 是該列值的數據類型。有些功能不須要返回值,這種狀況下 return_types 不是必須的。
函數體:函數定義的代碼集合。
注意:
1.2.1 golang函數不支持重載,一個包不能有兩個函數名同樣的函數。
1.2.2 函數也是一種類型,一個函數能夠賦值給變量。
Go 函數能夠返回多個值,例如:
package main import "fmt" func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("Google", "Runoob") fmt.Println(a, b) }
以上實例執行結果爲:
Runoob Google
(如下 「指定返回值」這句話, 僅指return後面直接跟着的返回值)
1.退出執行,不指定返回值
(1) 函數沒有返回值
package main import ( "fmt" ) func GetMoney(){ fmt.Println("money") return } func main(){ GetMoney() }
(2) 函數返回值有變量名
package main import ( "fmt" ) func GetMoney() (_amount int){ _amount = 88 fmt.Println("money: ",_amount) return } func main(){ var amount = GetMoney() fmt.Println("money: ",amount) }
2.退出執行,指定返回值
package main import ( "fmt" ) func GetMoney() (_amount int){ fmt.Println("money: ",_amount) return 88 } func main(){ var amount = GetMoney() fmt.Println("money: ",amount) } 運行結果: money: 0 money: 88
3.退出執行,指定返回值和指定默認值
package main import ( "fmt" ) func GetMoney() (_amount int){ _amount = 99 //若是return後面沒有指定返回值,就用賦給「返回值變量」的值 fmt.Println("money: ",_amount) return 88 //若是return後面跟有返回值,就使用return後面的返回值 } func main(){ var amount = GetMoney() fmt.Println("money: ",amount) } 運行結果: money: 99 money: 88
func add(arg…int) int { }
func add(a int, arg…int) int { }
func add(a int, b int, arg…int) int { }
由一個不帶函數名的函數聲明和函數體組成。
func main() { i := 1 go func(i int) { time.Sleep(100*time.Millisecond) fmt.Println("i =", i) } (i) i++ time.Sleep(1000*time.Millisecond) }
func a() { i := 0 defer fmt.Println(i) i++ return }
關閉文件句柄:
func read() { file := open(filename) defer file.Close() //其餘操做 }
鎖資源的釋放:
func read() { mc.Lock() defer mc.Unlock() //其餘操做 }
數據庫鏈接釋放:
func read() { conn := openDatabase() defer conn.Close() //其餘操做 }
一、輸入的使用
第一種寫法:fmt.Scanf("%d", &a)
第二種寫法:fmt.Scan(&a)
示例:
package main //必須有一個main包 import "fmt" func main() { var a int //聲明變量 fmt.Printf("請輸入變量a: ") //阻塞等待用戶的輸入 //fmt.Scanf("%d", &a) //別忘了& fmt.Scan(&a) fmt.Println("a = ", a) }
#執行結果:
請輸入變量e:666 a = 666
Scanf %d只能接收整型,不能接收字符型
因此在輸入字符型變量時應該使用fmt.Scanf(「%c」,&a)
格式 | 含義 |
---|---|
%% | 一個%字面量 |
%b | 一個二進制整數值(基數爲2),或者是一個(高級的)用科學計數法表示的指數爲2的浮點數 |
%c | 字符型。能夠把輸入的數字按照ASCII碼相應轉換爲對應的字符 |
%d | 一個十進制數值(基數爲10) |
%f | 以標準記數法表示的浮點數或者複數值 |
%o | 一個以八進制表示的數字(基數爲8) |
%p | 以十六進制(基數爲16)表示的一個值的地址,前綴爲0x,字母使用小寫的a-f表示 |
%q | 使用Go語法以及必須時使用轉義,以雙引號括起來的字符串或者字節切片[]byte,或者是以單引號括起來的數字 |
%s | 字符串。輸出字符串中的字符直至字符串中的空字符(字符串以'\0‘結尾,這個'\0'即空字符) |
%t | 以true或者false輸出的布爾值 |
%T | 使用Go語法輸出的值的類型 |
%x | 以十六進制表示的整型值(基數爲十六),數字a-f使用小寫表示 |
%X | 以十六進制表示的整型值(基數爲十六),數字A-F使用小寫表示 |