日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go语言基础之1--标识符、关键字、变量和常量、数据类型、Go的基本程序结构、Golang的特性...

發(fā)布時間:2023/11/29 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go语言基础之1--标识符、关键字、变量和常量、数据类型、Go的基本程序结构、Golang的特性... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?一、前言

當我們項目較為簡單時,我們在src目錄下新建一個該項目目錄,里面存放源碼文件即可,見下圖:

當我們一個項目較為復(fù)雜時,我們可以在src目錄下新建一個該項目目錄,在針對該項目不同模塊創(chuàng)建不同目錄,比如說logic(邏輯)、views(圖片渲染)、data(數(shù)據(jù)庫)等等。

二、第一個Go程序hello world

2.1 代碼

package mainimport ("fmt" )//程序執(zhí)行的入口函數(shù) func main() {fmt.Print("hello world")fmt.Printf("hello world,%d\n ", 100)fmt.Println("hello world") }

2.2 相關(guān)解釋

??go語言中所有的代碼(源碼)不能夠單獨存在,必須隸屬于一個包。例:第一行package main表示hello.go屬于main包的。

? 如果是為了將代碼編譯成一個可執(zhí)行程序,那么package必須是main;如果是為了將代碼編譯成庫,那么package則沒有限制。

? fmt 是go的一個系統(tǒng)庫,所以如果我們要使用這個系統(tǒng)庫就需要將fmp這個包導(dǎo)入,才能引用這個包中的函數(shù)和方法,而println就是fmt庫中的一個函數(shù),fmt.println()可以打印輸出。

? go語言中,很多東西都是強制性的,需要去慢慢習(xí)慣。對于python等解釋性語言,在函數(shù)中隨便寫一些語句,就可以執(zhí)行了,但go不行,go語言中,程序執(zhí)行的入口就是main函數(shù)(當編譯完后,就是一個可執(zhí)行程序,可雙擊執(zhí)行,可執(zhí)行程序的入口就是執(zhí)行main函數(shù)中的內(nèi)容)。?

? 注意:go語言中函數(shù)的花括號“{”一定要放在函數(shù)名所在行的行末。此處為強制性要求。

? fmt庫中,print表示打印內(nèi)容,printf表示格式化輸出(%d表示占位符,指的是整型int,\n表示換行),println表示換行輸出。

2.3 編譯并執(zhí)行

1、在當前終端中編譯該程序?qū)嵗?/p>

?

無任何輸出是好事,表示程序無問題。

2、我們可以發(fā)現(xiàn)在當前目錄已經(jīng)出現(xiàn)了一個可執(zhí)行程序

?

hello.exe就是編譯后生成的可執(zhí)行程序文件。

3、我們可以在當前終端目錄下直接執(zhí)行該可執(zhí)行程序(windows環(huán)境也可以直接去所在目錄雙擊執(zhí)行即可)。

?

2.4 其他案例

上述hello world當我們在windows環(huán)境雙擊執(zhí)行時,會發(fā)現(xiàn)打開后就退出了,這是正常的,程序執(zhí)行完自然就退出了。此處我們我來寫一個等待用戶輸入之后,在退出的小例子。

注意:print是打印(輸出),而此處我們是要輸入,用到scan,因為是輸入,所以要定義一個變量來接收輸入的這個值。

package mainimport ("fmt" )//程序執(zhí)行的入口函數(shù) func main() {fmt.Print("hello world")fmt.Printf("hello world,%d\n ", 100)fmt.Println("hello world")var a intfmt.Scan(&a) //等待用戶輸入然后退出 }

執(zhí)行后的結(jié)果:

三、go基本命令介紹

基本命令

?? go run 快速執(zhí)行g(shù)o文件,就像執(zhí)行腳本一樣(先編譯(編譯好文件放在一個臨時文件下)在執(zhí)行。注意:需指定要編譯的源碼文件

??? go build 編譯程序,生成二進制可執(zhí)行文件(將當前目錄下所有源碼編譯

??? go install 安裝可執(zhí)行文件到bin目錄(編譯并安裝,針對當前目錄下所有源碼

??? go test 執(zhí)行單元測試或壓力測試

??? go env 顯示go相關(guān)的環(huán)境變量

???go fmt 格式化源代碼(當我們從網(wǎng)絡(luò)上找了些源碼格式混亂時,需要針對該源碼文件打開終端執(zhí)行g(shù)ofmt –w .)

一般來說我們的ide在我們保存時就已經(jīng)將代碼格式化了。

補充:

1、GOPATH下全路徑編譯

當處于GOPATH路徑下進行編譯時,要寫源代碼所在全路徑時,不用寫src,因為go中已經(jīng)固定死了(默認就是往src目錄下去找)。情況如下圖所示(圖中GOPATH為d:\project):

?

go intsall同go build一模一樣。

四、go的程序結(jié)構(gòu)

4.1 關(guān)于注釋

單行注釋://
多行注釋:/* */

4.2 程序結(jié)構(gòu)

? ?一個項目(目錄)下所有代碼文件應(yīng)只屬于一個包(多個會報錯),也就是說一個目錄下寫的是一個大的功能,這些個功能只能歸屬于一個包。

?? go源碼按package進行組織,并且package要放到非注釋的第一行

?? 一個程序(代碼)只有一個main函數(shù)

?? main函數(shù)是程序的執(zhí)行入口

?? 代碼是可執(zhí)行程序,那么package必須是main,包是main是定死的,函數(shù)也必須是main也是定死的,否則就會報錯(因為package已經(jīng)聲明了是main,那就表明這是可執(zhí)行程序,如果此時函數(shù)不是main那就會報錯。)package(包) main 和func(函數(shù))main是一一對應(yīng)的。

可參考下圖更好理解main。

4.3 包的概念

1. 和python一樣,把相同功能的代碼放到一個目錄,稱之為包

2. 包可以被其他包引用

3. main包是用來生成可執(zhí)行文件,每個程序只有一個main包

4. 包的主要用途是提高代碼的可復(fù)用性

五、標識符和關(guān)鍵字

1、標識符是用來表示Go中的變量名或者函數(shù)名,以字母或_開頭。后面跟著字母、 _或數(shù)字

如:_ab28 和ab_28就是合法的,88ab就是不合法的。

2、關(guān)鍵字是Go語言預(yù)先定義好的,有特殊含義的標識符。

?

?

六、變量和常量

6.1 變量

語法:var identifier type

var 變量名 變量類型

變量名 = 值

注意

1、go語言中定義的變量必須被用到,否則會報錯(但是也有解決辦法:如果定義的變量d未被用到,我們可以使用 _ = d 來忽略變量d

2、同時定義變量和賦值可以一步完成。

3、type可以省略不寫,系統(tǒng)會自動根據(jù)后面給定的值進行判別

4、Go語言中變量命名推薦駝峰語法

例1:

var a int var b string var c bool var d int = 8 var e string = "hello"

?

我們會發(fā)現(xiàn)當定義多個變量會顯得很繁瑣,每一個都必須寫var,其實可以不用每個都寫,具體見例2.

例2:

var (a int //0 不賦值默認為0b string //“” 不賦值默認為空c bool //false 不賦值默認為falsed int = 8 // 8e string = "hello" //hello )

例3打印變量小案例:

將上述定義的變量打印出來

package mainimport ("fmt" )var (a int //0 不賦值默認為0b string //“” 不賦值默認為空c bool //false 不賦值默認為falsed int = 8 // 8e string = "hello" //hello )func main() {fmt.Println(a)fmt.Println(b)fmt.Println(c)fmt.Println(d)fmt.Println(e) }

?執(zhí)行結(jié)果:

補充

var a int =10 可以簡寫為 a :=10(:=表示聲明并初始化變量

?6.2 常量

常量使用const 修飾,代表永遠是只讀的,不能修改。

語法:

const identifier [type] = value,其中type可以省略。

實例6-1???????? 例1:常規(guī)寫法

const b string = "hello world" const b = "hello world" const Pi = 3.1414926 const a = 9/3

?實例6-2???????? 例2:優(yōu)雅寫法

const(a = 1b = 2c = 3 )

?實例6-3???????? 例3:專業(yè)寫法1

如果我們上述定義的的常量a、b、c是有序的,我們可以使用下面的專業(yè)寫法

const (a = iotab = iotac = iota ) # iota表示自動從0開始,第一行為0(以行為單位,和行數(shù)綁定,第一行為0,第二行為1,第三行為2),往后遞增。a=0,b=1,c=2 簡寫為如下:一般用簡寫 const (a = iotabc )

?注意:iota是與行數(shù)相綁定的,與行號相關(guān),下面這個例子來加深印象

package mainimport ("fmt" )const (a = 5b = iotacd = 3efg = iota )func main() {fmt.Printf("a=%d b=%d c=%d d=%d e=%d f=%d g=%d", a, b, c, d, e, f, g) }

執(zhí)行結(jié)果:

解釋:

第一行a=5

第二行b=iota,因為是第二行了了所以b=1(第一行iota=0,第二行iota=1)

第三行c,因為第二行是b = iota,所以相鄰c = iota,所以c=2

第四行d=3

第五行e相鄰d=3,所以e=3

第六行f也是等于3

第七行g(shù)=iota,因為是第7行了所以g=6(注意第一行是以0開始而不是1)

實例6-4???????? 例4 專業(yè)寫法2

const(a = 1 << iotabc ) #iota可以方便的迭代一個值從0以步長1遞增,0,1,2,3,4,5 結(jié)果:a=1,b=2,c=4

?七、數(shù)據(jù)類型和操作符

7.1 布爾類型

a. var b bool 和 var b bool = true 和 var b = false

b. 操作符 == 和 !=

c. 取反操作符: !b

d. && 和 || 操作符

e. 格式化輸出占位符: %t

實例7-1

package mainimport ("fmt" )func main() {var b = falsevar (c = trued bool = false)_ = d //因為此程序d變量沒有用到,此處我們將d變量賦值給_,_就相當于忽略的意思if !b {fmt.Printf("b is false\n")}if !b && c {fmt.Printf("result is true\n")}/*if b || c == true {}*/if b || c {fmt.Printf("or operation\n")} }

?執(zhí)行結(jié)果如下:

7.2 整數(shù)和浮點數(shù)類型

a. 符號:int8(1字節(jié))、int16(2字節(jié))、int32(4字節(jié))、int64(8字節(jié))

b. 無符號:uint8、uint16、uint32、uint64

c. int和uint和操作系統(tǒng)平臺相關(guān)(比如說:64位系統(tǒng)占8字節(jié),32位系統(tǒng)占4字節(jié),所以如果跨平臺的話最好采用a和b帶數(shù)字下標的形式,這樣可擴展性比較好)

d. float32(4字節(jié))和float64(8字節(jié))浮點類型

e. 所有整數(shù)初始化為0,所有浮點數(shù)初始化為0.0,布爾類型初始化為false

f. Go是強類型語言,不同類型相加以及賦值是不允許的(比如說:定義為int,永遠是int類型。int和int32是不同類型,不能相加也不能互相賦值)

g. 那怎么樣才能實現(xiàn),不同類型相加呢?

?比如:int和int32類型想要相加,那必須得做一個強制轉(zhuǎn)換,轉(zhuǎn)換成相同類型數(shù)據(jù)才能相加或者賦值

h. 輸出占位符:整數(shù)%d, %x十六進制, %f浮點數(shù)

?補充:

1字節(jié)===8個二進制位===11111111 相當于最大值256(2^8) 如果有符號的話最大值是127

實例7-2

package mainimport ("fmt" )func main() {var a int = 10var b int32 = 10var c intc = a + int(b)var d int = int(b)fmt.Print(a, b, c, d)fmt.Println() //不輸出任何值表示換行fmt.Printf("%x\n", c) //輸出16進制c }

?執(zhí)行結(jié)果:

7.3 字符串類型

a. var str string

b. var str string = “hello world”

c. 字符串輸出占位符%s

d. 萬能輸出占位符: %v (當不確定數(shù)據(jù)具體是什么類型時,用什么占位符時,系統(tǒng)自動幫我們進行轉(zhuǎn)換。)

package mainimport ("fmt" )func main() {var b string = "hello"var c = "hello"fmt.Printf("b=%v and c=%s\n", b, c) }

?執(zhí)行結(jié)果:

?

7.4 字符串的兩種表示方式

a. 雙引號, “”,可以包含控制字符

b. 反引號, ``,所有字符都是原樣輸出

c.字符必須用單引號括起來,不能用雙引號,字符串用雙引號。

實例7-3

package mainimport ("fmt" )func main() {var str = "hello world\n\n" // \n是控制字符換行,""的話可以包含控制字符,輸出換行var str2 = `hello \n \n \n` // ``所有字符都會原樣輸出fmt.Println("str=", str)fmt.Println("str2=", str2) }

?輸出結(jié)果:

實例7-4

package mainimport ("fmt" )func test_str1() {var b string = "hello\n\n\n"var c = "hello"fmt.Printf("b=%v and c = %s\n", b, c) } func test_str2() {var b string = `床前明月光\n,疑是地上霜。舉頭望明月,低頭思故鄉(xiāng)。`fmt.Printf("b %s\n", b) } func test_char() {var c rune //rune用來表示一個utf8的字符c = 20320var d byte //byte表示一個字節(jié)d = 'd'//c = '你' //'你'的utf8編碼是20320,所以下面代碼輸出‘你’var e rune = '喊'fmt.Printf("c=%c d=%c e=%c\n", c, d, e) // %c輸出字符 } func main() {test_str1()test_str2()test_char() }

?輸出結(jié)果:

補充:go語言中支持以下格式輸出。

目前printf支持以下格式的輸出,例如:

printf("%c",a);輸出單個字符。

printf("%d",a);輸出十進制整數(shù)。

printf("%f",a);輸出十進制浮點數(shù).

printf("%o",a);輸出八進制數(shù)。

printf("%s",a);輸出字符串。

printf("%u",a);輸出無符號十進制數(shù)。

printf("%x",a);輸出十六進制數(shù)。

7.5 操作符

a. 邏輯操作符, == 、 != 、 <、 <=、 >=

b. 算數(shù)操作符, +、 -、 *、 /、 %

八、 Go程序的基本結(jié)構(gòu)延伸

1. 任何一個代碼文件隸屬于一個包

2. import 關(guān)鍵字,引用其他包:

import "fmt"

import("os")

通常習(xí)慣寫成:

import (

"fmt"

"os"

)

3. 開發(fā)可執(zhí)行程序, package main,

并且有且只有一個main入口函數(shù)。

4. 包中函數(shù)調(diào)用:

a. 同一個包中函數(shù),直接用函數(shù)名調(diào)用

b. 不同包中函數(shù),通過包名+點+函數(shù)名進行調(diào)用

5. 包訪問控制規(guī)則:

a. 大寫意味著這個函數(shù)/變量是可導(dǎo)出

b. 小寫意味著這個函數(shù)/變量是私有的,包外部不能訪問

實例8-1

目錄結(jié)構(gòu):

calc:做第三方庫

calc.go

package calcimport ("fmt" )func Add(a int, b int) int {var c = a + bfmt.Printf("add result:%d\n", c)return c }

?編譯安裝為靜態(tài)庫:

編譯后的靜態(tài)庫:(main包為可執(zhí)行包,編譯后的文件為.go后綴二進制文件,main之外的包,編譯后存在pkg下,后綴為.a文件)

可執(zhí)行程序main.go

package mainimport ("day1/calc""fmt" )func main() {var c intc = calc.Add(2, 3)fmt.Printf("c=%d\n", c) }

?執(zhí)行結(jié)果:

九、 Go語言特性

1. 垃圾回收

a. 內(nèi)存自動回收,再也不需要開發(fā)人員管理內(nèi)存

b. 開發(fā)人員專注業(yè)務(wù)實現(xiàn),降低了心智負擔

c. 只需要new分配內(nèi)存,不需要釋放

?

2. 天然并發(fā)

a. 從語言層面支持并發(fā),非常簡單(用戶態(tài)實現(xiàn),避免了用戶態(tài)和內(nèi)核態(tài)的頻繁切換)

b. goroutine(協(xié)程),輕量級線程,創(chuàng)建成千上萬個goroute成為可能(go成千上萬個goroutine在用戶態(tài)跑時,可能操作系統(tǒng)(內(nèi)核)只有幾千個線程再跑,java有多少個線程在用戶態(tài)跑,就有多少個線程在內(nèi)核態(tài)跑)

c. 基于CSP(Communicating Sequential Process)模型實現(xiàn)(其實就是goroutine+channel,線程之間通信借助管道)

實例9-1???????? ?

原有程序案例是:

calc.go

package calcimport ("fmt" )func Add(a int, b int) int {var c = a + bfmt.Printf("add result:%d\n", c)return c }

main.go 示例1

package mainimport ("day1/calc""fmt" )func main() {var c intcalc.Add(2, 3)fmt.Printf("c=%d\n", c) }

目前是同步執(zhí)行的,如果想要異步執(zhí)行,只需要如下(標紅)操作即可,那樣就變成多線程的了,代碼示例如下:

main.go

示例2:

package mainimport ("day1/calc""fmt" )func main() {var c intgo calc.Add(2, 3)fmt.Printf("c=%d\n", c) }

?接下來演示效果:

如果是單線程跑,代碼示例如示例1:執(zhí)行結(jié)果如下:

解釋:單線程跑的話,是同步的,先調(diào)函數(shù)打印出加法計算結(jié)果,然后在打出c的值。單線程是順序輸出,固定輸出的。

如果是多線程跑,代碼示例如示例2:實行結(jié)果如下:

解釋:

go calc.Add(2, 3) 相當于起了一個線程再跑,fmt.Printf("c=%d\n", c),是另一個線程(主線程)再跑,為什么最后只打印出一個c=0,是因為主線程執(zhí)行完了,退出了,其他的線程就沒有機會執(zhí)行了。多線程是哪一個線程調(diào)度的快,哪一個線程就優(yōu)先輸出,主線程優(yōu)先輸出的話,其他線程就沒有機會執(zhí)行了。

?

3. channel

a. 管道,類似unix/linux中的pipe(隊列)

b. 多個goroute之間通過channel進行通信

c. 支持任何類型

實例9-2

package mainimport ("fmt" )func main() {p := make(chan int, 3)p <- 1p <- 2var b intb = <-pfmt.Printf("b = %d\n", b) }

輸出結(jié)果:

解釋:

make(chan int,3):chan就是管道類型關(guān)鍵字,int表示管道中放什么類型數(shù)據(jù),3表示管道空間,也就是管道的容量

p <- 1:就表示往管道中放數(shù)據(jù)

b = <- p:表示從管道中把數(shù)據(jù)取出來給變量b

輸出的b的結(jié)果為1:,是因為隊列先進先出。

?

注意:

管道容量為3,當放入的數(shù)據(jù)多于3個時,就會報死鎖的錯誤。

代碼如下:

執(zhí)行結(jié)果:

死鎖是最近新版本加入,舊的版本會直接卡在哪里等待。

?

4. 多返回值

a. 一個函數(shù)返回多個值

實例9-3 ? ? ? ??

定義多個返回值,就要返回多個,不然會報錯,都是一一對應(yīng)的。

實例9-4

package mainimport ("fmt" )func Calc(a int, b int) (int, int) {return a + b, a - b }func main() {a1, b1 := Calc(2, 5)fmt.Printf("a1=%d b1=%d\n", a1, b1) }

?執(zhí)行結(jié)果:

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/forever521Lee/p/9263402.html

總結(jié)

以上是生活随笔為你收集整理的Go语言基础之1--标识符、关键字、变量和常量、数据类型、Go的基本程序结构、Golang的特性...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。