Go函数返回变量 切片类型默认值

本文探讨了Go语言中函数返回值的默认值规则,指出普通类型如int会有默认值,而引用类型如切片和map在未初始化时不会分配内存。通过示例展示了指针类型如果不初始化会导致空指针异常,强调了在使用前必须进行初始化。此外,还提到了切片作为返回值时,如果没有初始化则为nil,并可能导致运行时错误。最后,通过示例说明了在某些情况下,数据库操作库可能会自动初始化切片。

对于go的函数返回变量,会有默认值,比如int是0,string是""。
对于引用类型,比如切片,map作为函数返回变量时,是不会分配地址的。
对于普通类型,是会分配地址的。

普通类型

//根据脚本id查询脚本
func (d *ScriptDao) GetByScripId(id int) (v model.Script, err error) {
	//script with id
	fmt.Println(v.Id)
	fmt.Println(v.Create_time)
	fmt.Println()
	v = model.Script{Id: id}
	//根据id查询,把结果放进v里
	_, err = initials.DemoDB.Get(&v)
	if err != nil {
		return v, err
	}
	return v, nil
}

输出

0
0001-01-01 00:00:00 +0000 UTC

由此可见:普通类型类型里的字段是默认值,对于普通的对象如time,就也是默认值。

指针类型

对于指针类型,go不会为其初始化,所以会出现空指针异常的问题

//根据脚本id查询脚本
func (d *ScriptDao) GetByScripId(id int) (v *model.Script, err error) {
	//script with id
	v.Id = 11
	fmt.Println(v.Id)
	fmt.Println(v.Create_time)
	fmt.Println()
	v.Id = 1
	//v = model.Script{Id: id}
	//根据id查询,把结果放进v里
	_, err = initials.DemoDB.Get(v)
	if err != nil {
		return v, err
	}
	return v, nil
}

报错指向v.Id = 11

0xc0001902c8
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0xb9d901]

goroutine 1 [running]:

修改一下代码,多了一步初始化

//根据脚本id查询脚本
func (d *ScriptDao) GetByScripId(id int) (v *model.Script, err error) {
	//script with id
	v = new(model.Script)
	v.Id = 11
	fmt.Println(v.Id)
	fmt.Println(v.Create_time)
	fmt.Println()
	v.Id = 1
	//v = model.Script{Id: id}
	//根据id查询,把结果放进v里
	_, err = initials.DemoDB.Get(v)
	if err != nil {
		return v, err
	}
	return v, nil
}

程序正常运行

11
0001-01-01 00:00:00 +0000 UTC

引用类型

func (d *ScriptDao) GetByUnameAndType(uname, t string) (scripts []model.Script, err error) {
	//初始化脚本集
	//scripts = make([]model.Script, 0)
	fmt.Println(scripts, "////")
	fmt.Println(scripts[0].Id)
	err = initials.DemoDB.Where("username=? and script_type=?", uname, t).Find(&scripts)
	fmt.Printf("%p", scripts)

	if err != nil {
		return scripts, err
	}
	return scripts, nil
}

**一个nil值的切片长度和容量都为0,没有分配内存

[] ////
panic: runtime error: index out of range [0] with length 0

所以切片和指针差不多类似。

ps:写这个也是无聊,因为我发现我往xorm的Find里必须要传引用,也就是变量的地址。对于切片来说也是这样。我就想我这个返回的参数有没有被初始化(赋予地址),毕竟之前学切片的时候,就需要注意切片一定要初始化。
经过刚刚的验证,很显然切片没有被初始化。换句话说是nil。我就想怎么可能&nil呢。
然而代码这么写竟然也可以运行。

func (d *ScriptDao) GetByUname(uname string) (scripts []model.Script, err error) {
	//初始化脚本集
	//scripts = make([]model.Script, 0)
	err = initials.DemoDB.Where("username=?", uname).Find(&scripts)

	if err != nil {
		return scripts, err
	}
	return scripts, nil
}

so,在Find里我看到了(嗯,应该是他给初始化了)
在这里插入图片描述

<think>首先,用户的问题是:“我想查询Go语言中int32类型默认值及修改方法 请问Go语言 int32 类型默认值是什么,如何修改 int32 变量的值” 根据系统级指令,我需要: - 使用中文回答。 - 行内数学表达式用 `$...$`,但这里可能不需要数学表达式。 - 独立公式用 `$$...$$`,但可能不适用。 - LaTeX语法正确。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题。 - 引用站内引用:[^1], [^2], [^3], [^4]。 从用户消息中,引用的内容是关于Go语言和Java的数据类型默认值: - 引用[1]:提到Go语言各数据类型默认值,包括int、float32、bool、string等。 - 引用[2]:详细说明Go语言变量声明后的默认值,包括int8、byte、uint等整形默认值为0,float32、float64为0,bool为false,string为"",复合类型为nil,数组根据类型。 - 引用[3]:类似,用fmt.Printf输出默认值。 - 引用[4]:Java中int类型默认值为0。 用户的问题是针对Go语言的int32类型,所以我应该聚焦在Go语言上。 关键点: 1. Go语言中int32类型默认值:根据引用[2],整形如int8、int16等默认值为0。int32应该也是0。 2. 如何修改int32变量的值:在Go中,变量可以通过赋值操作修改值。 我的回答结构: - 先确认默认值。 - 然后解释如何修改值。 - 使用清晰的步骤。 - 添加引用标识。 - 最后生成相关问题。 逐步回答: 1. **默认值**:在Go语言中,任何变量在声明后未赋值时,都有一个零值(zero value)。对于int32类型,零值是0。这基于引用[2]:"整形如int8、byte、int16、uint、uintprt等,默认值为0。" 2. **修改值**:要修改int32变量的值,只需使用赋值操作符 `=`。例如: - 声明变量:`var num int32` - 赋值:`num = 42` 或直接初始化:`var num int32 = 42` - 或者使用短变量声明:`num := int32(42)` 添加代码示例来演示。 最后,生成相关问题: - 基于主题,如Go语言其他类型默认值、错误处理等。 引用标识: - 在回答中,当引用内容时,添加 [^数字]。 - 例如,提到默认值时引用 [^2]。 完整回答结构: - 开头:直接回答问题。 - 解释默认值。 - 解释修改方法,带示例代码。 - 结尾:生成相关问题。</think>### Go语言中 int32 类型默认值及修改方法 在Go语言中,变量在声明后未显式赋值时,会被自动赋予一个**零值(zero value)**。下面我将逐步解释 int32 类型默认值以及如何修改其值,确保回答清晰易懂。 #### 1. int32 类型默认值 - **默认值**:对于 int32 类型(一种32位有符号整数),其零值为 **0**。这意味着如果您声明一个 int32 变量但未初始化,Go语言会自动将其设置为 0。 - **原因**:Go语言规定所有数值类型(包括 int、int32、float32 等)的零值均为 0。布尔类型为 false,字符串为 "",复合类型(如切片指针)为 nil[^2]。 - **代码验证**: ```go package main import "fmt" func main() { var num int32 // 声明 int32 变量,未赋值 fmt.Printf("int32 默认值: %d\n", num) // 输出: 0 } ``` 运行此代码将输出 `int32 默认值: 0`,确认默认值为 0[^2][^3]。 #### 2. 如何修改 int32 变量的值 修改 int32 变量的值非常简单,主要通过赋值操作符 `=` 实现。以下是几种常见方法: - **基本赋值**:在声明后直接赋值。 ```go var num int32 // 声明变量默认值为 0 num = 42 // 修改值为 42 fmt.Println(num) // 输出: 42 ``` - **声明时初始化**:在声明变量的同时赋值,避免默认值。 ```go var num int32 = 42 // 声明并初始化为 42 fmt.Println(num) // 输出: 42 ``` - **短变量声明**:使用 `:=` 简化声明和赋值(适合函数内部)。 ```go num := int32(42) // 短声明,直接设置为 42 fmt.Println(num) // 输出: 42 ``` - **通过运算修改**:结合算术运算(如 +、-、*)动态更新值。 ```go num := int32(10) // 初始值 10 num = num * 2 // 修改为 20 fmt.Println(num) // 输出: 20 ``` **关键点**: - 修改值只需使用 `=` 操作符,Go语言是静态类型语言,赋值时类型必须匹配(例如,不能将字符串赋给 int32)。 - 如果变量是结构体字段或全局变量,修改方式相同[^2][^3]。 #### 注意事项 - **零值的重要性**:Go语言的零值机制确保变量总有有效值,避免未定义行为,这在并发编程中尤其有用[^2]。 - **错误处理**:如果赋值时类型不匹配(如 `num = "hello"`),编译器会报错,确保代码安全。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值