Go语言学习第二课:数据类型和变量

值类型和引用类型

所有像 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)
}
相关推荐
newerp14 小时前
Go net/http 标准库基础
后端·程序员·go
26519405112648015 小时前
01-整体架构与高可用
go
程序员爱钓鱼17 小时前
Go if 判断详解
前端·后端·go
名字还没想好☜1 天前
Go 的 unsafe.Pointer 实战:零拷贝 []byte↔string 转换与三条铁律
开发语言·后端·golang·go·unsafe
阿里云云原生1 天前
阿里云联合 Datadog,补齐 Go 可观测性最后短板
云原生·go
可观测性用观测云1 天前
零码改造!Go 语言应用上报观测云完整最佳实践
go
斐波那契数列1 天前
参考react 实现一个golang gui
go
程序员爱钓鱼2 天前
Go 运算符详解
后端·面试·go
angryshan2 天前
goLang配置断点流程
go·bug
名字还没想好☜3 天前
Go 的 sync.Cond 实战:用条件变量做等待/通知,比忙轮询省 CPU
开发语言·数据库·后端·golang·go