Go基礎學習二之經常使用命令、包、變量、常量、控制語句、range

Go編程語言:支持併發、垃圾回收的編譯型系統級編程語言!本文主要是按照無聞的《Go 編程基礎》開源視頻學習並記錄筆記。git

1、go語言經常使用命令

go get 獲取遠程包(需提早安裝git)
go run 運行
go build 測試編譯(package main 的文件)
go fmt 格式化代碼
go install 編譯包文件和整個程序
go test 運行測試文件(**_test.go是測試文件,命名本身文件的時候須要注意)
go doc 查看文檔(本地官網 godoc -http=:8080 & 後臺執行)

咱們能夠將go的官網放到本地:github

godoc -http=:8080

而後咱們能夠訪問本地8080端口:golang

http://localhost:8080/編程

Go環境變量與工做目錄:GOPATH下須要創建 3個目錄(bin存放編譯後生成的可執行文件;pkg存放編譯後生成的包文件;src存放項目源碼)數組

2、go 語法結構

一、Go導入package的格式

package main包含main函數
一個程序有且只有一個main包和一個main函數
package 要放在非註釋的第一行
package 後加import,import 引入非main包
通常建議package的名稱和目錄名一致 pacage 名稱不要使用駝峯標記法,使用下劃線
var 全局變量
type 基本類型 好比:type newtype struct/interface{(內容)}併發

改包名:app

import abc "fmt"/import . "fmt"

調用的時候編程語言

abc.Println/Println

不推薦使用.那種,容易混淆函數

只有packagemain 的包能夠包含main函數,一個可執行程學習

test.go

package ok
// package main  這裏故意將main 包名寫錯

import "fmt"

func main(){
    fmt.Println("Hello, World")
}

若是咱們運行的程序裏邊沒有 package main 包,則執行會報錯;
➜ src go run myfirstgo/test.go go run: cannot run non-main package

  • 導入包以後,就可使用格式<PackageName>.<FuncName>
  • 若是導入包以後 未調用 其中的函數類型將會報出編譯錯誤

import and not used:"io";

二、package別名

當使用第三方包時,包名可能會很是接近或相同,此時就可使用別名來進行區別和調用

import "fmt"

// 使用別名
import std "fmt"
std.Println("Hello,world")

省略調用

// 省略調用
import . "fmt"
Println("Hello,world")

注意點:
1.不建議使用省略調用,易混淆
2.不能夠和別名同時使用

3.可見性規則

Go語言中,使用 大小寫 來決定該常亮、變量、類型、接口、結構或函數,是否能夠被外部包所調用:
根據約定,函數名首字母小寫即爲private

func getField(){
  // ...
}

函數名首字母大寫即爲public

func Print(){
  // ...
}

完整示例:

package main

// 導入其餘的包
import "fmt"     // 第一種導入方法
/*
import{
    "fmt"
    "io"
    "os"
}
*/

// 常量的定義
const PI = 3.14

// 全局變量的聲明與賦值
var name = "gopher"

// 通常類型聲明
type newType int

// 結構的聲明
type gopher struct{}

// 接口的聲明
type golang interface{}

// 由 main 函數做爲程序入口點啓動
func main(){
    fmt.Println("Hello, World")
}

牛刀小試:
既然導入多個包能夠進行簡寫,那麼聲明多個常亮、全局變量或通常類型(非接口、非結構)是否也可使用一樣的方法呢?

定義常亮:

const(
  PI = 3.14
  const1 = 1
  Radis = 10
)

全局變量的聲明與賦值:

var (
 name = "corwien"
 age  = 20
 address = "guangzhou"
)

通常類型聲明:

type (
 newType int
 type1 float32
)

3、類型與變量

1.類型

一、布爾類型:bool
長度:1字節
取值範圍:true,false
注意事項:不能夠用數字表明true或false

二、整型:int/uint
-根據運行平臺可能爲32或64位

三、8位整型:int8/uint8
-長度:1字節
-取值範圍:-128~127/0~255

四、字節型:byte(uint8別名

五、16位整型:int16/uint16
-長度:2字節
-取值範圍:-32768~32767/0~65565

六、32位整型:int32(rune)/uint32
-長度:4字節
-取值範圍:-32768~32767/0~65565

七、浮點型:float32/float64
-長度:4/8字節
-小數位:精確到7/15小數位

八、複數:complex64/complex128
-長度:8/16字節
足夠保存指針的3二、64位整數型:uintptr

九、其餘值類型:

  • array、struct、string

十、引用類型:

  • slice,map,chan

十一、接口類型:interface
十二、函數類型:func,能夠賦值給變量

類型零值

零值並不等於空值,而是當變量被聲明爲某種類型後的默認值,一般狀況下值類型的默認值爲0,bool爲false, string爲空字符串

類型別名

type (
  byte int8
  rune int32
  文本 string
)

// 使用中文類型,牛逼啊
var b 文本
b = "你好哈親"

2.變量

2.1 單個變量的聲明與賦值

  • 變量的聲明格式:var <變量名稱><變量類型>
  • 變量的賦值格式:<變量名稱> = <表達式>
  • 聲明的同時賦值:var <變量名稱>[變量類型] = <表達式>

示例:

var a int // 變量的聲明
a = 123   // 變量的賦值

// 變量聲明的同時賦值
var a int = 123

// 上行的格式可省略變量類型,由系統推斷
var c = 123

// 變量聲明與賦值的最簡寫法
d := 678

d := 678 冒號的做用就是代替關鍵字 var 的

2.2 多個變量的聲明與賦值

  • 全局變量的聲明可使用var()的方式進行簡寫
  • 全局變量的聲明不能夠省略var,但可使用並行方式
  • 全部變量均可以使用類型推斷
  • 局部變量不可使用var()的簡寫,只能使用並行方式

舉例:

var(
  // 使用常規方式
  a = 'hello'
 
  // 使用並行方式以及類型推斷
   b,c = 1,2
  // d := 3 // 不能夠省略 var
)

多個變量的聲明

// 多個變量的聲明
var a, b, c int

// 多個變量的賦值
a, b, c = 1, 2, 3

// 多個變量聲明的同時賦值
var d, e, f int = 4, 5, 6

// 省略變量類型,有系統推斷
var g, h, m  = 7, 8, 9

// 多個變量聲明與賦值的最簡寫法
n, o, p := 10, 11, 12

2.3 變量的類型轉換

  • Go中不存在隱式轉換,全部類型轉換必須顯示聲明
  • 轉換只能發生在兩種相互兼容的類型之間
  • 類型轉換的格式:
// 當變量未在前邊申明過,則須要冒號:,若是已經聲明過,則不須要冒號
<ValueA>[:] = <TypeOfValueA>(<ValueB>)

示例:

// 在相互兼容的兩種類型之間轉換
var a float32 = 1.1
b := int(a)

// 如下表達式沒法經過編譯
var c bool = true
d := int(c)
全局變量的聲明不能夠省略var 局部變量不可使用var()的方式簡寫

思考
嘗試運行下邊的代碼,開會發生什麼,並思考爲何?

// 變量類型轉換,整數轉爲字符,會發生什麼呢?
func main() {
    var a int = 65
    b := string(a)
    fmt.Println(b)
}

4、常量與運算符

一、常量的定義

  • 常量的值在編譯時就已經肯定
  • 常量的定義格式與變量基本相同
  • 等號右側必須是常量或者常量表達式
// 定義單個常量
const a int = 1
const b = 'A'
const {
  text = "123"
  length = len(text)
  num = b * 20
}

// 同時定義多個變量
const i, j, k = 1, "2", "3"
const(
  text2, length2, num2 = "234", len(text2), k * 10
)

二、常量的初始化規則與枚舉

  • 在定義常量組時,若是不提供初始值,則表示將使用上行的表達式
  • 使用相同的表達式不表明具備相同的值
  • iota是常量的計數器,從0開始,組中每定義1個常量自動遞增1
  • 經過初始化規則與iota能夠達到枚舉的效果
  • 每遇到一個 const 關鍵字,iota就會重置爲0

示例:

const (
    // a與b都爲"A"
    a = "A"
    b
    c = iota
    d // d的值爲3
)

const(
  e = iota
  f // f 的值爲1
)

// 星期枚舉
const(
  // 第一個常量不可省略表達式
    Monday = iota
    Tuesday
    Wednesday
    Thursday
    Firday
    Saturday
    Sunday
)

三、運算符

  • Go中的運算符均是從左至右結合
    優先級(從高到底)
  • ^ ! (一元運算符)
  • * / % << >> & &^
  • + - | ^ (二元運算符)
  • == != < <= >= >
  • <- (專門用於channel)
  • &&
  • ||

四、指針

Go雖然保留了指針,但與其餘編程語言不一樣的是,在Go當中不支持指針運算以及「->」運算符,而直接採用「.」選擇符來操做指針目標對象的成員

  • 操做符「&」取變量地址,使用「*」經過指針間接訪問目標對象
  • 默認值爲 nil 而非NULL
func main() {
    a := 1
    var p *int = &a;

    // fmt.Println(p)   打印地址:0xc42000e228
    fmt.Println(*p)    // 打印結果: 1
    
}

五、遞增遞減語句

在Go當中, ++ 與 -- 是做爲語句而並非做爲表達式

5、控制語句

一、判斷語句if

  • 條件表達式沒有括號,這和其餘語言不太同樣
  • 支持一個初始化表達式(能夠是並行方式)
  • 左大括號必須和條件語句或else在同一行
  • 支持單行模式
  • 初始化語句中的變量爲block級別,同時隱藏外部同名變量
  • 1.0.3版本中的編譯器Bug

示例:

package main


import "fmt"  


func main() {

    a := true

    // 初始化變量,在塊裏邊初始化,做用域只是在該區塊中
    if a, b, c := 1, 2, 3; a+b+c > 6 {
        fmt.Println("大於6")  
        fmt.Println(a)

    } else {
        fmt.Println("小於等於6")
        fmt.Println(a)

    }

    fmt.Println(a)  
    
}

打印結果:

➜  myfirstgo go run if.go
小於等於6
1
true

二、循環語句for

  • Go 只有 for 一個循環語句關鍵字,但支持3種形式
  • 初始化和步進表達式能夠是多個值
  • 條件語句每次循環都會被從新檢查,所以不建議在條件語句中使用函數,儘可能提早計算好條件並以變量或常量代替
  • 左大括號必須和條件語句在同一行

for 循環的三種形式:
1.最簡單的

func main() {
    
    a := 1
    for {
        a++
        if a > 3 {
            break
        }
    }
    fmt.Println(a)
}

二、條件語句判斷

func main() {
    
    a := 1
    for a <= 3 {
        a++
    }
    fmt.Println(a)
}

三、最經常使用的一種方式

func main() {
    
    a := 1
    for i := 0; i < 3; i++ {
        a++
    }
    fmt.Println(a)
}

三、選擇語句switch

  • 可使用任何類型表達式做爲條件語句
  • 不須要寫break,一旦條件符合自動終止
  • 如但願繼續執行下一個case,需使用fallthrough語句
  • 支持一個初始化表達式(能夠是並行方式),右側需跟分號
  • 左大括號必須和條件語句在同一行

示例:

// switch

func main() {
    a := 1
    switch a {
    case 0:
        fmt.Println("a=0")
    case 1:
        fmt.Println("a=1")
    default:
        fmt.Println("Nothing")
    }
    fmt.Println(a)
}
func main() {
    a := 1
    switch {
    case a >= 0:
        fmt.Println("a=0")
        fallthrough
    case a >= 1:
        fmt.Println("a=1")
    }
    fmt.Println(a)
}
func main() {
    
    switch a := 1; {
    case a >= 0:
        fmt.Println("a=0")
        fallthrough
    case a >= 1:
        fmt.Println("a=1")
    }
    
}

四、跳轉語句goto,break,continue

  • 三個語法均可以配合標籤使用
  • 標籤名區分大小寫,若不使用會形成編譯錯誤
  • Break與continue配合標籤可用於多層循環的跳出
  • Goto 是調整執行位置,與其餘2個語句配合標籤的結果並不相同

示例:

func main() {
// 標籤
LABLE:
  for {
      for i := 0; i < 10; i++ {
          if i > 3 {
              break LABLE
          }

      }
  }
    
    fmt.Println("ok")
}
func main() {
LABLE:
      for i := 0; i < 10; i++ {
          for {
              continue LABLE
              fmt.Println(i)
          }
  }
    
    fmt.Println("ok")
}

6、語言範圍 Range

Go 語言中 range 關鍵字用於for循環中迭代數組(array)、切片(slice)、通道(channel)或集合(map)的元素。在數組和切片中它返回元素的索引值,在集合中返回 key-value 對的 key 值。

示例:

package main
import "fmt"
func main() {
    //這是咱們使用range去求一個slice的和。使用數組跟這個很相似
    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    fmt.Println("sum:", sum)
    //在數組上使用range將傳入index和值兩個變量。上面那個例子咱們不須要使用該元素的序號,因此咱們使用空白符"_"省略了。有時侯咱們確實須要知道它的索引。
    for i, num := range nums {
        if num == 3 {
            fmt.Println("index:", i)
        }
    }
    //range也能夠用在map的鍵值對上。
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }
    //range也能夠用來枚舉Unicode字符串。第一個參數是字符的索引,第二個是字符(Unicode的值)自己。
    for i, c := range "go" {
        fmt.Println(i, c)
    }
}

運行結果:

sum: 9
index: 1
a -> apple
b -> banana
0 103
1 111

相關資源:
Go 編程基礎
Go學習筆記整理

相關文章
相關標籤/搜索