值类型和引用类型
所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值:
当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝
数据类型
布尔型
go
var b bool = true
数字类型
整型
go
package main
import "fmt"
func main() {
// -128 到 127
var a int8 = 1
// -32768 到 32767
var b int16 = 1
// -2147483648 到 2147483647
var c int32 = 1
// -9223372036854775808 到 9223372036854775807
var d int64 = 1
// 0 到 255
var e uint8 = 1
// 0 到 65535
var f uint16 = 1
// 0 到 4294967295
var g uint32 = 1
// 0 到 18446744073709551615
var h uint64 = 1
fmt.Println(a, b, c, d, e, f, g, h)
}
浮点型
go
package main
import "fmt"
const (
trillion = 1e12
)
func main() {
// 1. float32
var temperature float32 = 36.6
fmt.Printf("体温: %.1f (%T)\n", temperature, temperature)
// 2. float64(推荐) 最常用的浮点类型,精度高(约 15 位有效数字),适合大多数场景。
var gdp float64 = 21.4 * trillion
fmt.Printf("GDP: %.2f (%T)\n", gdp, gdp)
// 不写类型时,默认是 float64
var pi = 3.141592653589793
// 输出: float64
fmt.Printf("类型: %T\n", pi)
// 3. complex64
var signal complex64 = 2 + 3i
fmt.Printf("信号: %v, 实部=%v, 虚部=%v\n", signal, real(signal), imag(signal))
// 4. complex128
// 这里的 i 是个"标签",意思是"这是第二维的数字"。
// 3 是"水平方向"
// 4i 是"垂直方向"
// 加在一起,就表示一个点或一个方向
var root complex128 = complex(3, 4)
fmt.Printf("%v (%T)\n", root, root)
}
其他数字类型
go
package main
import (
"fmt"
"unsafe"
)
func main() {
// ASCII 码 'A'
// 用途:常用于处理字符串、二进制数据(如文件、网络传输)。
var b byte = 65
// byte 和 uint8 可以互换使用
// var data uint8 = 255
// 输出: A (65)
fmt.Printf("b = %c (%d)\n", b, b)
// 用途:Go 字符串是 UTF-8 编码,rune 是处理中文等多字节字符的正确方式(类似 Java 的 char,但支持 Unicode)。
var r rune = '世'
// '世' 的 Unicode 码点
// var code int32 = 19990
// 输出: 世, code = 19990
fmt.Printf("r = %c, code = %d\n", r, r)
// 注意:uint 大小不固定,在 64 位系统上是 64 位,32 位系统上是 32 位。
// 建议:如果需要确定大小,使用 uint32 或 uint64。
var counter uint = 1000
var length uint = 42
fmt.Printf("counter = %d, length = %d\n", counter, length)
// int 是最常用的整型,Java 开发者可以类比为 long(但 Java 的 int 是 32 位固定,Go 的 int 不固定)。
var age int = 30
var score int = -5
fmt.Printf("age = %d, score = %d\n", age, score)
// uintptr 主要用于系统编程、指针运算,普通业务开发几乎不会用到。
// 使用 unsafe.Pointer 需导入 "unsafe" 包,属于非安全操作,需谨慎
var ptrValue uintptr
// 示例:获取变量地址并转为 uintptr(底层操作,一般不用)
x := 42
ptrValue = uintptr(unsafe.Pointer(&x))
fmt.Printf("地址: %v, 值: %d\n", ptrValue, x)
}
字符串类型
go
package main
import "fmt"
func main() {
var word string = "Hello"
fmt.Println(word)
}
派生类型
- 指针类型(Pointer)
- 数组类型
- 结构化类型(struct)
- Channel 类型
- 函数类型
- 切片类型
- 接口类型(interface)
- Map 类型
go
package main
import "fmt"
// 定义一个结构体
type Person struct {
Name string
Age int
}
// 定义一个函数类型
type MathFunc func(int, int) int
func main() {
fmt.Println("=== Go 核心类型:定义变量并使用 ===\n")
// 1. 指针类型(Pointer)
fmt.Println("1. 指针类型")
var age = 30
var ptr *int = &age // ptr 指向 age 的地址
*ptr = 35 // 通过指针修改原值
fmt.Printf("age = %d\n", age) // 输出: 35
// 2. 数组类型
fmt.Println("\n2. 数组类型")
var nums [3]int = [3]int{10, 20, 30}
fmt.Printf("数组: %v\n", nums)
fmt.Printf("第一个元素: %d\n", nums[0])
// 3. 结构体类型(struct)
fmt.Println("\n3. 结构体类型")
p := Person{Name: "Alice", Age: 35}
fmt.Printf("结构体: %+v\n", p)
// 4. Channel 类型
fmt.Println("\n4. Channel 类型")
ch := make(chan string) // 创建 channel
go func() {
ch <- "任务完成" // 发送消息
}()
msg := <-ch // 接收消息
fmt.Printf("从 channel 收到: %s\n", msg)
// 5. 函数类型
fmt.Println("\n5. 函数类型")
var add MathFunc = func(a, b int) int {
return a + b
}
result := add(3, 4)
fmt.Printf("函数调用结果: %d\n", result)
// 6. 切片类型(Slice)
fmt.Println("\n6. 切片类型")
tags := []string{"go", "web"}
tags = append(tags, "cloud") // 动态添加
fmt.Printf("切片: %v, 长度=%d\n", tags, len(tags))
// 7. 接口类型(interface)
fmt.Println("\n7. 接口类型")
var any interface{} = "Hello"
fmt.Printf("接口保存字符串: %v\n", any)
any = 100
fmt.Printf("接口保存整数: %v\n", any)
// 实际应用:多态打印
printValue("Go")
printValue(42)
printValue([]int{1, 2, 3})
// 8. Map 类型
fmt.Println("\n8. Map 类型")
config := map[string]string{
"host": "localhost",
"port": "8080",
}
config["env"] = "dev" // 添加键值对
fmt.Printf("Map 配置: %v\n", config)
if port, exists := config["port"]; exists {
fmt.Printf("服务端口: %s\n", port)
}
fmt.Println("\n所有类型演示完毕!")
}
// 辅助函数:演示接口的多态性
func printValue(v interface{}) {
switch val := v.(type) {
case string:
fmt.Printf("这是字符串: '%s'\n", val)
case int:
fmt.Printf("这是整数: %d\n", val)
case []int:
fmt.Printf("这是整数切片: %v\n", val)
default:
fmt.Printf("未知类型: %T\n", val)
}
}
变量
go
package main
import "fmt"
// 这种因式分解关键字的写法一般用于声明全局变量
var (
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
func main() {
// 声明变量的一般形式
var a string = "Runoob"
fmt.Println(a)
// 一次声明多个变量
var b, c int = 1, 2
fmt.Println(b, c)
// 没有初始化就为零值
var d int
fmt.Println(d)
// bool 零值为 false
var e bool
fmt.Println(e)
// 指针、切片、映射、通道、函数、接口 以下几种类型为 <nil> [] map[] <nil> <nil> <nil>
var a1 *int
var a2 []int
var a3 map[string]int
var a4 chan int
var a5 func(string) int
var a6 error // error 是接
fmt.Println(a1, a2, a3, a4, a5, a6)
// 根据值自行判定变量类型
var a7 = "Runoob"
fmt.Printf("%T\n", a7)
iniValue := 1
fmt.Println(iniValue)
g, h := 123, "hello"
fmt.Println(g, h)
}
常量
go
package main
const (
Unknown = 0
Female = 1
Male = 2
)
const (
a = iota
b = iota
c = iota
)
const (
a1 = iota
b2
c3
)
func main() {
const LENGTH int = 10
println(LENGTH)
//多重赋值
const a, b, c = 1, false, "str"
println(a, b, c)
println(Unknown, Female, Male)
// iota
//iota,特殊常量,可以认为是一个可以被编译器修改的常量。
//iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
const (
a2 = iota //0
b2 //1
c2 //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)
println(a2, b2, c2, d, e, f, g, h, i)
}