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)
}
相关推荐
研究司马懿10 小时前
【云原生】Gateway API高级功能
云原生·go·gateway·k8s·gateway api
梦想很大很大1 天前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰1 天前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
却尘1 天前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤1 天前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
mtngt112 天前
AI DDD重构实践
go
Grassto3 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto5 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室6 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题6 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo