Go基础编程 - 04 - 基本类型、常量和变量


目录

    • [1. 基本类型](#1. 基本类型)
    • [2. 常量](#2. 常量)
    • [3. 变量](#3. 变量)
      • [3.1 变量声明](#3.1 变量声明)
      • [3.2 自定义类型、类型别名](#3.2 自定义类型、类型别名)
      • [3.3 类型推导](#3.3 类型推导)
      • [3.4 类型断言](#3.4 类型断言)
      • [3.5 类型转换](#3.5 类型转换)

Go 基础编程 - 03 - init、main、_


1. 基本类型

  • 支持八进制、十六进制,以及科学记数法

  • 零值:只做了声明,但未做初始化的变量被给予的缺省值。每个类型的零值都会依据该类型的特性而被设定。

  • 单引号(''):定义一个字符;返回rune类型,也就是码点字面量(Unicode code point)。

  • 双引号(""):定义字符串

  • 反引号(``):通常使用于字符串换行、正则表达式

  • byteuint8的别名,代表ASCII码的一个字符;runeint32别名,代表一个UTF-8字符

类型 长度(字节) 零值 说明
布尔值 bool 1 false true|false
整型 int, uint 4或8 0 与操作系统位数相同(32或64位)
整型 int8(byte), uint8 1 0 取值:-128 ~ 127, 0 ~ 255;byte是uint8 的别名
整型 int16, uint16 2 0 取值:$-32768 ~ 32767, 0 ~ 65535
整型 int32, uint32(rune) 3 0 取值:-2\^{31} ~ 2\^{31}-1, 0 ~ 2\^{32}-1;rune是int32 的别名
整型 int64, uint64 4 0
浮点 float32 4 0.0
浮点 float64 8 0.0
复数 complex64 8
复数 complex128 16
字符串 string "" UTF-8 字符串
结构体 struct 值类型
引用类型 slice nil 切片:[n]Type
引用类型 map nil 字典:[Type]Type{}
引用类型 chan nil 管道
接口 interface(any) nil interface{}
函数 func nil

2. 常量

常量是恒定不变的,常量定义时必须赋值;常量只会在编译期间存在,不存储内存中,不可被寻址。

iota

  • iota是Go语言的常量计数器,只能在常量的表达式中使用。
  • iotaconst关键字出现时将被重置为0。
  • const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。
  • 使用iota能简化定义,在定义枚举时很有用。
go 复制代码
package main

import "fmt"

// 常量是恒定不变的,常量定义时必须赋值。
const Pi = 3.14
// 多个常量一起声明
const (
    str = "string"
    i = 100
)
// const 同时声明多个变量,如果省略了值,则上一行的值(或表达式)相同
const ( 
    n1 = 100    // 100
    n2          // 100
    n3          // 100
)

// 常量声明使用iota,每新增一行计数一次
const ( 
    m1 = iota   // 0, 索引由0开始
    m2          // 1
    _           // 2 即使忽略,iota同样计数
    n4 = 200    // 200 插队声明, iota同样计数
    n5          // 200 使用省略值规则   
    m3 = iota   // 5  重新使用iota规则
    m4          // 6 
)

// 多个iota定义在一行(缺省值和iota结合)
const (
	a, b = iota + 1, iota + 2 //1,2   iota = 0
	c, d                      //2,3   iota = 1,iota + 1 = 2, iota + 2 = 3
	e, f                      //3,4   iota = 2,iota + 1 = 3, iota + 2 = 4
)

func main() {
    fmt.Println(n1, n2, n3, n4, n5) // 100 100 100 200 200
    fmt.Println(m1, m2, m3, m4)     // 0 1 5 6
    fmt.Println(a, b, c, d, e, f)   // 1 2 2 3 3 4
}

3. 变量

3.1 变量声明

  • Go语言的变量声明后必须使用

  • 变量声明时会自动被初始化成其类型的默认值

go 复制代码
    // 声明格式:var name Type
    var i int64
    var (
        x int64
        y float64
    )

    // 初始化
    var i1 int64 = 1    
    var name, age = "小猫", 1

    // 短变量声明
    s := "Short var"

    // 变量重声明
    // 1. 不支持单个变量重声明;
    // 2. 当有新的变量和已被声明的变量同时声明时,允许使用:=重声明已有变量,
    // 3. 重声明时,变量类型不可改变
    i, j := 10, 100  // 存在新的变量j
    // 4. 变量重声明是在某一个代码块内,并不包含它的任何子代码块。
    if true {
        i := "Set string type"  // 子代码块中i为新的字符串变量(重名变量)
    }

    // 匿名变量(_),用于忽略多个返回值中的某些值
    x, _ := "X", 100
    println(x)

3.2 自定义类型、类型别名

自定义类型:通过Type关键字定义,是定义一个全新的类型。

类型别名:使用"="定义,type TypeAlias = Type,TypeAlias只是Type的别名,本质上属于同一个类型。

  • 潜在类型:某个类型其本质上是哪种类型。
  • 内置基本类型:uint8 别名 byteint32 别名 runeinterface{} 别名 any
go 复制代码
type AString = string       
var s AString = "Alisa" 
fmt.Printf("%T \n", s)      // string

type BString string         
bs := BString("New Type")
fmt.Printf("%T \n", bs)     // main.BString

// 1. 潜在类型相同的不同类型之间可以进行类型转换。
s = AString(bs)
// 2. 对于集合类的类型[]string与[]BString的潜在类型不同,分别为[]string和[]BString。
s1 := []string{"a", "a", "a", "a"}
s2 := []BString{"b", "b", "b", "b"}
fmt.Printf("%T %T \n", s1, s2) // []string  []main.BString
// 3. 即时两个不同类型的潜在类型相同,他们的值也不能进行判等或比较,他们的变量之间也不能赋值。
s = bs                      // 报错: cannot use bs (variable of type BString) as type string in assignment

3.3 类型推导

也叫隐式类型转换。有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。

go 复制代码
var a := 1.2    // float64
b := 1 + a      // float64  可兼容类型允许隐式转换,编译器可以将 1 隐式转换为 float64 类型

c := 1          // 编译器不允许对标识符引用的值进行强制转换
d := a + c      // invalid operation: c + a (mismatched types int and float64)。

3.4 类型断言

类型断言是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或具体的类型。

语法:value, ok := x.(T)value := x.(T) (此表达式若断言失败则会产生panic)

x:表示一个接口类型

T:表示一个具体的类型(或接口)

value:表示返回的 x 的值

ok:bool值,表示 x 的值类型是否为 T

go 复制代码
var x interface{}

x = 10
fmt.Printf("%T \n", x.(interface{}))        // int

v, ok := x.(int)        // v = 10, ok = true
v2, _ := x.(string)     // v2 = ""

v3 := x.(int)           // v3 = 10
v4 := x.(string)        // 产生 panic: interface conversion: interface {} is int, not string

// 如果 x 是 nil 接口值时,无论 T 是什么类型,断言都会失败,v 的值为 T 的缺省值。
x = nil
v, ok = x.(int)
fmt.Printf("v = %v, ok = %v \n", v, ok)     // v = 0, ok = false

// 配合 switch
switch x.(type) {
    case int:
        fmt.Println("The type of x is int.")
    case string:
        fmt.Println("The type of x is string.")
    default:
        fmt.Println("unknown type.")
}

3.5 类型转换

类型转换包含:类型断言、强制转换、显示转换、隐式转换(类型推导)。

go 复制代码
// 隐式转换
const a = 123
var i = 0
var i1 int64 = 1.0      // 可兼容类型允许隐式转换
var i2 int64 = 1.1      // 不兼容,产生错误
i3 = a * i1             // float64

// 显示转换/强制转换
var n int64 = 100
f := float64(n)                 // int to float64
ns := strconv.Itoa(n)           // int to string
si, _ := strconv.Atoi("123")    // string to int

// 指针类型强制转换 unsafe
var p int = 30
var prs *int = &p
var p2 *int64 = (*int64)(unsafe.Pointer(prs))
fmt.Printf("p addr = %d \n prs = %d \n p2 = %d, p2 addr = %d \n", &p, prs, *p2, p2)
相关推荐
jerry6094 小时前
7天用Go从零实现分布式缓存GeeCache(改进)(未完待续)
分布式·缓存·golang
杜杜的man5 小时前
【go从零单排】Closing Channels通道关闭、Range over Channels
开发语言·后端·golang
甘橘籽10 小时前
【RPC】 gRPC、pb基本使用--经验与总结
golang
杜杜的man10 小时前
【go从零单排】HTTP客户端和服务端
开发语言·http·golang
材料苦逼不会梦到计算机白富美10 小时前
golang分布式缓存项目 Day6 防止缓存击穿
分布式·缓存·golang
杜杜的man13 小时前
【go从零单排】Environment Variables环境变量
golang
材料苦逼不会梦到计算机白富美15 小时前
golang HTTP基础
http·golang·iphone
友大冰17 小时前
Go 语言已立足主流,编程语言排行榜24 年 11 月
开发语言·后端·golang
hummhumm18 小时前
第 10 章 - Go语言字符串操作
java·后端·python·sql·算法·golang·database
__AtYou__1 天前
Golang | Leetcode Golang题解之第563题二叉树的坡度
leetcode·golang·题解