04-Go語(yǔ)言常量和變量

Go數(shù)據(jù)類型

  • C語(yǔ)言的數(shù)據(jù)類型


    image
  • GO語(yǔ)言數(shù)據(jù)類型


    image
  • GO數(shù)據(jù)類型占用的內(nèi)存空間


    image
package main

import (
    "fmt"
    "unsafe"
)

func main() {
    // 有符號(hào)的整型
    fmt.Println("int size = ", unsafe.Sizeof(int(0)))  // 8
    fmt.Println("int8 size = ", unsafe.Sizeof(int8(0)))  // 1
    fmt.Println("int16 size = ", unsafe.Sizeof(int16(0)))  // 2
    fmt.Println("int32 size = ", unsafe.Sizeof(int32(0)))  // 4
    fmt.Println("int64 size = ", unsafe.Sizeof(int64(0)))   // 8
    // 結(jié)論: int會(huì)根據(jù)系統(tǒng)自動(dòng)調(diào)整,如果系統(tǒng)是64的,那么int就會(huì)變成int64,
    // 如果系統(tǒng)是32的, 那么int 就會(huì)變成32位



    // 無(wú)符號(hào)的整型
    fmt.Println("uint size = ", unsafe.Sizeof(uint(0)))   //  8
    fmt.Println("uint8 size = ", unsafe.Sizeof(uint8(0)))   // 1
    fmt.Println("uint16 size = ", unsafe.Sizeof(uint16(0)))   // 2
    fmt.Println("uint32 size = ", unsafe.Sizeof(uint32(0)))   // 4
    fmt.Println("uint64 size = ", unsafe.Sizeof(uint64(0)))   // 8

    // 字符類型
    fmt.Println("byte size = ", unsafe.Sizeof(byte(0)))   // 1
    fmt.Println("rune size = ", unsafe.Sizeof(rune(0)))   // 4
    fmt.Println("中文字符 = ", unsafe.Sizeof('好'))   // 4

    // 浮點(diǎn)類型
    fmt.Println("float32 size = ", unsafe.Sizeof(float32(0)))   // 4
    fmt.Println("float64 size = ", unsafe.Sizeof(float64(0)))   // 8

    // 布爾類型
    fmt.Println("true size = ", unsafe.Sizeof(true))   //  1
    fmt.Println("false size = ", unsafe.Sizeof(false))   // 1


}

  • 注意點(diǎn):
    • 在GO語(yǔ)言中我們可以通過(guò)Sizeof來(lái)計(jì)算數(shù)據(jù)類型占用的內(nèi)存大小
    • 使用Sizeof函數(shù)必須導(dǎo)入unsafe這個(gè)包
    • 通過(guò)unsafe.Sizeof()來(lái)調(diào)用這個(gè)方法
    • Sizeof的首字母必須大寫
    • Go語(yǔ)言中int類型,會(huì)根據(jù)系統(tǒng)自動(dòng)調(diào)整占用內(nèi)存的字節(jié)數(shù)
    • 如果是64位系統(tǒng), 那么int就是int64, 占用 8個(gè)字節(jié)
    • 如果是32位系統(tǒng), 那么int就是int32, 占用 4個(gè)字節(jié)

GO語(yǔ)言變量

  • 變量: 可以改變的數(shù)據(jù)稱為變量
  • 定義變量: 就是告訴系統(tǒng)需要分配多大的內(nèi)存空間來(lái)存儲(chǔ)數(shù)據(jù)
  • 格式:
    • 1.var 變量名稱 數(shù)據(jù)類型
    • 2.var 變量名稱 數(shù)據(jù)類型 = 值
    • 3.var 變量名稱 = 值
    • 4.變量名稱 := 值
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        // 先定義后初始化
        var num int
        num = 666
        fmt.Printf("num = %d\n", num)   // 666
    
        // 定義的同時(shí)初始化
        var num1 int =  123
        fmt.Println("num1 = ", num1)
    
        // 定義的同時(shí)初始化, 并省略數(shù)據(jù)類型
        var num2 = 234
        fmt.Println("num2 = ", num2)
        // fmt.Println("int sizeof = ", unsafe.Sizeof(num2))
    
        // 定義的同時(shí)初始化, 并省略數(shù)據(jù)類型和var
        // := 做了兩件事
        //  1. 先定義一個(gè)變量
        //  2. 給定義的變量賦值
         num3 := 100
         fmt.Println("num3 = ", num3)
    
         // num4 int:= 23
         // := 定義變量的同時(shí)不能添加數(shù)據(jù)類型
    
         var num5 := 555
         // := 定義變量的同時(shí)不能添加 var 
        fmt.Println("num4 = ", num5)
    }
    
    

連續(xù)定義多個(gè)變量

  • 格式:
    • 1.可以通過(guò)逗號(hào)來(lái)定義多個(gè)變量
    // 先定義變后初始化
    var a , b , c int
    a = 1
    b = 2
    c = 3
    
    // 定義變量的同時(shí)初始化
    var a , b, c int = 1, 2, 3
    
    
    • 2.可以使用變量組來(lái)同時(shí)定義多個(gè)變量
    // 先定義變量后初始化
    var(
        a int 
        b int
        c int
    )
    a = 1
    b = 2
    c = 3
    
    
    // 定義變量同時(shí)初始化
    var (
        a int = 1
        b int = 2
        c int = 3
    )    
    
    // 注意點(diǎn): 變量組中不能使用 := 來(lái)定義變量
    // var (
    //    a := 1
    //    b := 2
    // )
    

定義變量的注意點(diǎn):

  • 定義變量的時(shí)候, 如果省略數(shù)據(jù)類型那么系統(tǒng)會(huì)自動(dòng)根據(jù)數(shù)值推斷出變量的數(shù)據(jù)類型
  • 使用 := 定義變量的時(shí)候, 那么不能寫var 也不能寫數(shù)據(jù)類型
  • 使用 := 定義變量的時(shí)候, 只能定義局部變量不能定義全局變量
  • 使用 := 定義變量的時(shí)候, 變量組中不能使用 := 的格式
  • 使用 := 定義多個(gè)變量的時(shí)候, 變量如果已經(jīng)定義過(guò)了那么將退化成賦值操作
// 定義一個(gè)變量
var num int = 234
// 對(duì)于num已經(jīng)定義過(guò)了, 那么將退化成賦值操作
num , value := 666, 777
fmt.Println("num = ", num, "value = ", value)
  • 重復(fù)定義變量編譯報(bào)錯(cuò)
    package main

    import "fmt"
    
    func main() {
    
        num := 234
        num := 666
        fmt.Println("num = ", num)
    }
    

全局變量和局部變量

  • 局部變量:
    • 含義: 定義在函數(shù)內(nèi)部的變量,以及函數(shù)的形參就稱為局部變量
    • 作用域: 從定義的哪一行開(kāi)始到遇到}和return,到代碼塊結(jié)束就釋放
    • 生命周期: 從程序運(yùn)行到哪一行才分配存儲(chǔ)空間, 離開(kāi)作用域就釋放空間
  • 全局變量:
    • 含義: 定義在函數(shù)外部的變量稱為全局變量
    • 作用域: 從定義哪一行開(kāi)始到文件的結(jié)尾
    • 生命周期: 程序一啟動(dòng)就分配存儲(chǔ)空間, 知道程序結(jié)束
  • 注意點(diǎn):
    • GO語(yǔ)言中不管是定義局部變量還是全局變量都不能出現(xiàn)同名的變量
    • GO語(yǔ)言中,如果定義一個(gè)局部變量, 但是沒(méi)用使用這個(gè)變量, 編譯報(bào)錯(cuò)
    • GO語(yǔ)言中,如果定義一個(gè)全局變量, 但是沒(méi)用使用這個(gè)變量, 編譯不會(huì)報(bào)錯(cuò)

數(shù)值類型和字符串類型之間的轉(zhuǎn)換

  • GO語(yǔ)言中只有顯示轉(zhuǎn)換, 沒(méi)有隱式轉(zhuǎn)換
  • 數(shù)據(jù)類型一般用于除了字符串和布爾類型以外的其他基本類型的轉(zhuǎn)換
package main

func main() {
    // go語(yǔ)言中只有顯示轉(zhuǎn)換沒(méi)有隱式轉(zhuǎn)換
    // 格式:數(shù)據(jù)類型(被轉(zhuǎn)換的數(shù)據(jù))

     num int = 3.14  // 報(bào)錯(cuò)
    fmt.Println("num = ", num)

     不能對(duì)一個(gè)常量進(jìn)行類型的強(qiáng)行轉(zhuǎn)換
    var num1 int = int(3.14)
    fmt.Println("num1 = ", num1)

    // 正確做法
    // go語(yǔ)言中數(shù)據(jù)類型必須一模一樣才能直接賦值
    var num3 float64 = 3.14
    var value int = int(num3)
    fmt.Println("value = ", value)  // 3

    // 特殊情況
    var ch byte = 'a'
    var num4 uint8 = ch    // type byte = uint8  本質(zhì)
    fmt.Println("num4 = ", num4)  // 97

    var ch1 rune = '好'
    var num5 int32 = ch1
    fmt.Println("num5 = ", num5)  // 22909 UTF -8

    // bool 類型不能轉(zhuǎn)換為整型
    //var flag bool = false
    //var num6 int = flag
    //fmt.Println("num6 = ", num6)

    // 整型也可以轉(zhuǎn)換成字符類型, 但是不推薦使用
    //var num7 int = 97
    //var str string = string(num7)
    //fmt.Println("str = ", str)   // a

}

  • 基本數(shù)據(jù)類型轉(zhuǎn)換成字符串類型
    • 方法一: strconv.FormatXxx()
    • 方法二: strconv.Itoa()
package main

import (
    "fmt"
    "strconv"
    "unsafe"
)

func main() {
    // 基本數(shù)據(jù)類型轉(zhuǎn)換為字符串類型
    // 1. strconv.FormatXxx()
    // 2. strconv.Itoa()

    // strconv.FormatInt()
    // func FormatInt(i int64, base int) string
    // 第一個(gè)參數(shù): 需要轉(zhuǎn)換的整數(shù), 必須是int64類型的
    // 第二個(gè)參數(shù): 轉(zhuǎn)換為多少進(jìn)制的字符串
    var num1 int = 9
    var str1 string = strconv.FormatInt(int64(num1), 10)
    var str2 string = strconv.FormatInt(int64(num1), 2)
    fmt.Println("str1 = ", str1) // 9
    fmt.Println("str2 = ", str2)// 1001
    var str3 string = strconv.FormatInt(int64(3), 10)
    fmt.Println("str3 = ", str3) // 3

    // strconv.FormatFloat()
    // func FormatFloat(f float64, fmt byte, prec, bitSize int) string
    // 第一個(gè)參數(shù): 需要轉(zhuǎn)換的小數(shù)
    // 第二個(gè)參數(shù): 按照什么格式轉(zhuǎn)換  'f' 小數(shù)格式,  'e' 指數(shù)格式
    // 第三個(gè)參數(shù): 保留多少位小數(shù), 傳入 -1按照原始類型的精度保留
    // 第四個(gè)參數(shù): 原始類型的標(biāo)志  float32 --> 32  float64 --> 64
    var  num2 = 3.14
    var  str4 string = strconv.FormatFloat(float64(num2), 'f', -1,32)
    fmt.Println("str4 = ", str4)  // 3.14
    fmt.Println("sizeof num2 = ", unsafe.Sizeof(num2))  // 8

    // strconv.FormatBool
    // func FormatBool(b bool) string
    var flag bool = false
    var str5 string = strconv.FormatBool(flag)
    fmt.Println("str5 = ", str5) // false

    // strconv.Itoa()
    // func Itoa(i int) string
    var num3 int = 233
    //var  num3 int64 = 332
    var str6 string = strconv.Itoa(int(num3))
    fmt.Println("str6 = ", str6)  // 233




}

  • 字符類型轉(zhuǎn)換為基本數(shù)據(jù)類型
    • 方法一: strconv.ParseXxx()
    • 方法二: strconv.Atoi()
package main

import (
    "fmt"
    "strconv"
)

func main() {
    // Go語(yǔ)言中字符串類型轉(zhuǎn)換為基本數(shù)據(jù)類型
    // strconv.ParseXxx()
    // strconv.Atoi()

    //  strconv.ParseInt()
    // func ParseInt(s string, base int, bitSize int) (i int64, err error)
    // 第一個(gè)參數(shù): 需要轉(zhuǎn)換的字符串
    // 第二個(gè)參數(shù): 被轉(zhuǎn)化的字符串保存的整數(shù)是多少進(jìn)制的(原來(lái)的字符是多少進(jìn)制的)
    // 第三個(gè)參數(shù): 期望轉(zhuǎn)換為多少位的整數(shù)
    // 返回值有兩個(gè)
    // 第一個(gè)返回值: 轉(zhuǎn)后之后的數(shù)值, 是int64 類型
    // 第二個(gè)返回值: 如果轉(zhuǎn)換成功返回nil, 如果轉(zhuǎn)換失敗就不是nil
    var str1 = "1010"
    // num, err := strconv.ParseInt(str1, 10, 8)
    num, err := strconv.ParseInt(str1, 2, 8)
    if err != nil{
        fmt.Println("轉(zhuǎn)換失敗")
    }else{
        fmt.Println("num = ", num)  // 9
        fmt.Printf("%T ", num) // int64
    }
    // strconv.ParseFloat()
    //func ParseFloat(s string, bitSize int) (float64, error)
    // 第一個(gè)參數(shù): 需要轉(zhuǎn)換的字符串
    // 第二個(gè)參數(shù): 要將字符串中的小數(shù)轉(zhuǎn)換為單精度還是雙精度, 單精度傳入32, 雙精度傳入64
    // 返回兩個(gè)返回值
    // 第一個(gè)返回值: 轉(zhuǎn)換成功之后的小數(shù), float64類型
    // 第二個(gè)返回值: 轉(zhuǎn)換成功返回 nil, 轉(zhuǎn)換失敗不為 nil
    str2 := "3.123456789"
    num1, err := strconv.ParseFloat(str2, 32)
    if err != nil{
        fmt.Println("轉(zhuǎn)換失敗")
    }else{
        fmt.Println("num1 = ", num1)
        fmt.Printf("%T", num1)  // float64
    }

    // strconv.ParseBool()
    //func ParseBool(str string) (bool, error)
    var str3 string = "false"
    flag, err := strconv.ParseBool(str3)
    fmt.Println("flag = ", flag) // false
    fmt.Printf("%T\n", flag)  // bool

    // strconv.Atoi()
    // func Atoi(s string) (int, error)
    // 傳入一個(gè)字符串
    // 返回兩個(gè)值, 第一個(gè)是轉(zhuǎn)換成功后的數(shù), 第二個(gè)返回值是 : 轉(zhuǎn)換成功返回nil,
    var str4 string = "99"
    num2, err :=  strconv.Atoi(str4)
    if err != nil{
        fmt.Println("轉(zhuǎn)換失敗")
    }else{
        fmt.Println("num2 = ", num2)
    }


}


GO語(yǔ)言常量

  • GO語(yǔ)言常量分為整型常量, 實(shí)型常量, 字符常量, 字符串常量, 自定義常量
  • 自定義常量
    • 格式: const 常量名稱 數(shù)據(jù)類型 = 值 或者 const 常量名稱 = 值
package main

import "fmt"

func main() {
    // 格式: const 變量名稱 數(shù)據(jù)類型 = 值
    const   num1 int = 222
    // num1 = 111   // 常量不能賦值, 否則報(bào)錯(cuò)
    fmt.Println("num1 = ", num1)

    // 給多個(gè)變量賦值
    // 格式: const 變量名1 , 變量名2 數(shù)據(jù)類型 = 值1, 值2
    const num2 , num3 int = 10, 20
    fmt.Println("num2 = ", num2, "num3 = ", num3)

    // 使用變量組給常量賦值
    const (
        num4 int = 33
        num5 int = 44
        num6 int = 55
    )
    fmt.Println(num4, num5, num6)

    // 變量組的定義多個(gè)變量的注意點(diǎn)
    // 如果常量沒(méi)有賦值, 那么默認(rèn)值就是上一行的取值
    //const  (
    //  a = 10
    //  b = 20
    //  c = 30
    //)
    // fmt.Println(a, b, c) // 10 20 30

    //const  (
    //  a = 10
    //  b = 20
    //  c
    //)
    // fmt.Println(a, b, c) // 10 20 20

    const(
        a , b = 10, 20
        c, d
    )
    fmt.Println(a, b) // 10, 20
    fmt.Println(c, d) // 10, 20




}

  • 注意點(diǎn):
    • 不能給常量賦值, 會(huì)報(bào)錯(cuò)
    • 在常量組中, 如果常量沒(méi)有賦值, 那么值為上一行的值
  • 枚舉常量
  • 格式
const (
    枚舉元素1 = 值
    枚舉元素2 = 值
)
package main

import "fmt"

func main() {
    // 枚舉類型的本質(zhì)就是整型常量
    // Go語(yǔ)言和C語(yǔ)言一樣都是從0開(kāi)始遞增, 每行遞增1
    /*const(
        male =  iota
        female = iota
        yy = iota
    )*/
    // 等同于下面的寫法
    const(
        male =  iota
        female
        yy
    )
    // 只要有一行出現(xiàn)了iota, 那么后續(xù)會(huì)自動(dòng)遞增

    fmt.Println("male = ", male)  // 0
    fmt.Println("female = ", female)  // 1
    fmt.Println("yy = ", yy)    //  2

    // 如果常量組中被打斷了, 那么就不會(huì)繼續(xù)遞增了,
    // 而是會(huì)按照常量的的方式處理, 不賦值就會(huì)等于上一行的值
    const (
        a = iota
        b = 888
        c
    )

    fmt.Println("a = ", a)  //  0
    fmt.Println("b = ", b)   // 888
    fmt.Println("c = ", c)   // 888



    // 如果常量組中的iota被打斷了, 但是后續(xù)又恢復(fù), 那么前面有多少行,就會(huì)遞增多少
    const (
        num1 = iota
        num2 = 111
        num3 = iota
    )
    fmt.Println("num1 = ",num1)   // 0
    fmt.Println("num2 = ",num2)   // 111
    fmt.Println("num3 = ",num3)   // 2




}

  • 注意點(diǎn):
    • Go語(yǔ)言和C語(yǔ)言的枚舉一樣,利用iota標(biāo)識(shí)符從0開(kāi)始遞增,每行增加1
    • 在常量組中, iota只要上一行出現(xiàn)了, 那么下一行不賦值也會(huì)遞增
    • 但是如果常量組中, 被常量打斷了, 那么就會(huì)等于上一行的值
    • 常量組如果被打斷,后續(xù)又恢復(fù),那么前面有多少行就會(huì)遞增多少
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容