欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > Go语言基础:数据类型

Go语言基础:数据类型

2025/4/2 19:49:56 来源:https://blog.csdn.net/DuanDuan0820/article/details/146770551  浏览:    关键词:Go语言基础:数据类型

一、基础数据类型:Go语言的积木块

1.1 数字类型全家福

package mainimport ("fmt"
)func main() {// 有符号整数类型var a int    = 42                        // int 类型,自动选择32或64位var b int8   = 127                       // int8 类型,8位有符号整数var c int16  = 32767                     // int16 类型,16位有符号整数var d int32  = 2147483647                // int32 类型,32位有符号整数var e int64  = 9223372036854775807       // int64 类型,64位有符号整数// 无符号整数类型var f uint   = 42                        // uint 类型,自动选择32或64位var g uint8  = 255                       // uint8 类型,8位无符号整数var h uint16 = 65535                     // uint16 类型,16位无符号整数var i uint32 = 4294967295                // uint32 类型,32位无符号整数var j uint64 = 18446744073709551615      // uint64 类型,64位无符号整数// 浮点数类型var k float32 = 3.14                     // float32 类型,32位浮点数var l float64 = 3.141592653589793        // float64 类型,64位浮点数// 复数类型var m complex64  = 1 + 2i                // complex64 类型,实部和虚部都是 float32var n complex128 = 1 + 2i                // complex128 类型,实部和虚部都是 float64// 打印每个变量的类型fmt.Printf("%T %T %T %T %T\n", a, b, c, d, e)fmt.Printf("%T %T %T %T %T\n", f, g, h, i, j)fmt.Printf("%T %T\n", k, l)fmt.Printf("%T %T\n", m, n)
}

1.2 字符与布尔类型

var ch byte = 'A'      		// ASCII字符
var unicodeCh rune = '中' // Unicode字符
var flag bool = true

1.3 字符串的特别之处

Go语言的字符串是不可变的,也就是说,一旦创建后就无法修改其中的内容。如果需要修改字符串的内容,通常的做法是将字符串转换成一个可变的字节切片([]byte)或字符切片([]rune),对切片进行修改后再转换回字符串。

s := "hello"
b := []byte(s)   // 将字符串转换为字节切片
b[0] = 'H'       // 修改字节切片中的内容
s2 := string(b)  // 将修改后的字节切片转换回字符串
fmt.Println(s2)  // 输出: "Hello"

二、复合数据类型:构建复杂结构

2.1 数组:刻板的容器

特点

  • 长度固定
  • 值类型(赋值会复制整个数组)
  • 类型包含长度信息:[3]int ≠ [5]int
var arr1 [3]int             	// [0 0 0]
arr2 := [...]int{1,2,3}     	// 编译器推导长度
arr3 := [2][3]int{{1,2}, {3}} // 多维数组

痛点时刻:当我们需要动态大小时怎么办?

2.2 切片:灵活的舞者

关键特性

  • 底层引用数组
  • 自动扩容机制
  • 长度 vs 容量
slice1 := make([]int, 3, 5) // 长度3,容量5
slice2 := arr2[1:3]         // 基于数组创建
slice3 := []int{1,2,3}      // 直接初始化// 动态操作
slice3 = append(slice3, 4)  // 自动扩容
copy(slice1, slice2)        // 复制元素

扩容条件

  • 当向切片中追加元素(使用append函数)时,如果切片的长度未超过容量,则直接在底层数组上进行追加。
  • 如果追加元素后长度超过容量,Go会创建一个新的底层数组,并将旧切片的数据复制到新数组中。

扩容策略(目的:平衡内存使用和性能,避免频繁的内存分配和数据拷贝)

  • 如果切片的当前容量小于1024,新的容量一般是原来的2倍。
  • 如果切片的当前容量大于等于1024,新的容量会增加为原来的1.25倍(具体倍数可能会根据实现细节有所不同)。

注意事项

  • 扩容会导致新的内存分配和数据拷贝,因此如果预先知道切片的最大容量,最好在创建切片时指定容量以减少扩容的开销。
  • 由于扩容会创建新的底层数组,因此在扩容后,旧的切片和新的切片将不再共享同一个底层数组。

2.3 映射:闪电查询专家

特点

  • 键的类型必须是可比较的,而值可以是任意类型。
  • Map是引用类型,赋值操作不会复制整个映射。
  • 内置函数 make 用于初始化 map,使用时需注意防止空指针异常。
  • map 本身并不是线程安全的。具体来说,如果多个 goroutine 同时对一个 map 进行读写操作而没有采取适当的同步措施,那么程序可能会出现竞态条件(race condition),这可能导致不可预测的行为或崩溃。
m1 := make(map[string]int)
m2 := map[string]int{"apple": 5,"pear":  3,
}// 安全操作
if count, exists := m2["banana"]; exists {fmt.Println(count)
}// 遍历(无序!)
for k, v := range m2 {fmt.Println(k, v)
}

2.4 结构体:自定义数据蓝图

type Person struct {Name stringAge  intContact struct {Phone stringEmail string}
}p := Person{Name: "Alice",Age:  30,
}
p.Contact.Phone = "123-4567"

三、变量 vs 常量:变与不变的哲学

3.1 变量声明三剑客

特点

  • 作用域:变量的作用域由声明的位置决定,在函数内声明的变量属于局部作用域,全局声明的变量则属于包级作用域。
  • 生命周期:局部变量随函数调用结束而销毁,而全局变量则在整个程序运行期间一直存在。
  • 可变性:变量在程序运行过程中其值是可以被修改的。
// 标准式
var x int = 10// 类型推导
var y = "hello"// 短声明(这种方式语法简洁,只能在函数内部使用,非常适合局部变量的声明,但不适用于全局变量。)
z := 3.14// 分组声明(不推荐)
var (a = 1b = true
)

3.2 常量的奥妙

常量的特点

  • 不可变性:常量一旦赋值便不能再被修改,适用于需要保持固定值的场景。
  • 作用域:与变量类似,常量也有作用域的概念,取决于它们的声明位置。
  • 编译期常量:常量的值在编译期间确定,因此在运行时具有更高的效率。
  • 无地址分配:常量没有在内存中占据一个特定的地址,因为它们的值是直接嵌入到使用它们的代码中的。
const PI = 3.1415
const (Red = iota   // 0Green        // 1Blue         // 2
)// 编译期计算
const MatrixSize = 10 * 10

关键差异

特性变量常量
可修改
内存地址
类型推导支持必须显式
作用域相同相同

3.3 生命周期探秘

var globalVar = "永生" // 包生命周期func demo() {localVar := "临时工" // 函数执行期间存在fmt.Println(localVar)
}

内存小剧场:当函数执行结束,"临时工"会被垃圾回收器请出场外~


四、互动与思考

在学习过程中,我鼓励大家不断思考并动手实践。以下是一些问题和讨论话题,希望你能参与进来:

  1. 数据类型选择:在你以往的开发经历中,有没有遇到过数据类型选择不当导致性能问题的情况?你认为如何在保证代码简洁的前提下选择合适的数据类型?
  2. 复合数据类型使用场景:你觉得在何种场景下数组更合适,何种场景下又应该优先选择切片或映射?分享你的思考和实际案例吧!
  3. 变量和常量的管理:在大型项目中,如何合理规划变量和常量的作用域和生命周期?这不仅关乎代码质量,也涉及到团队协作和维护成本。

欢迎大家在评论区留言讨论,我们一起分享心得,共同进步!

学习检查清单

✅ 能说出3种数字类型的区别
✅ 会正确使用切片扩容
✅ 能区分 var 与 := 的使用场景
✅ 知道常量为什么不能取地址

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词