
本文讲解如何通过返回结构体指针的方式,在 go 程序中将房间角色(如姓名、年龄)从不同房间函数安全、清晰地传递给后续处理函数,并修正原始代码中的变量作用域、函数签名和逻辑错误。
本文讲解如何通过返回结构体指针的方式,在 go 程序中将房间角色(如姓名、年龄)从不同房间函数安全、清晰地传递给后续处理函数,并修正原始代码中的变量作用域、函数签名和逻辑错误。
在 Go 中,函数内部声明的变量(如 Avatarname 和 Avatarage)具有局部作用域,无法被其他函数直接访问。原始代码中,这些变量在 westRoom() 等函数内定义后即被丢弃,导致 main() 中的 p.Name = Avatarname 编译失败(变量未定义)。正确做法是让每个房间函数返回角色信息——推荐使用 *Person 指针,既避免值拷贝开销,又支持 nil 安全判断。
首先,修正 Person 结构体与房间函数签名:
type Person struct {
Name string
Age int
}
func westRoom() *Person {
fmt.Println("You find yourself in a room with three walls, and a door behind you.")
fmt.Println("The opposite wall is a window, overlooking the sea")
return &Person{"Bill", 25}
}
func eastRoom() *Person {
fmt.Println("You find yourself in a room with a door on the walls to your left, right, and behind you")
fmt.Println("On the wall across from you is a painting of a mountain scene")
return &Person{"Mary", 33}
}
func northRoom() *Person {
fmt.Println("You find yourself in a room with a door on the wall behind you")
fmt.Println("You see several statues of people standing around the room")
return &Person{"Joe", 58}
}
func southRoom() *Person {
fmt.Println("You find yourself in a room with a door on the wall in front and behind you")
return &Person{"Abagail", 67}
}
func lostRoom() *Person {
fmt.Println("You are unable to find a room in a maze filled only with rooms")
fmt.Println("It's almost like the programmer didn't know what he was doing")
return nil // 表示无有效角色
}
接着,更新 main() 中的流程:接收返回的 *Person,并仅在非 nil 时调用后续函数:
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
func main() {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
var p *Person
switch r1.Intn(4) {
case 0:
p = westRoom()
case 1:
p = eastRoom()
case 2:
p = northRoom()
case 3:
p = southRoom()
default:
p = lostRoom()
}
if p != nil {
avatar(p)
appearance(p)
} else {
fmt.Println("No valid avatar available.")
}
}
最后,修正 avatar 和 appearance 函数签名与逻辑(注意:原代码中 if p.Name == "Bill" || "Joe" 是非法语法,Go 不支持链式字符串比较):
func avatar(p *Person) {
if p.Name == "Bill" || p.Name == "Joe" {
fmt.Println("You see a man standing in the middle of the room")
} else {
fmt.Println("You see a woman standing in the middle of the room")
}
}
func appearance(p *Person) {
if p.Age > 50 {
fmt.Println("They look old")
} else {
fmt.Println("They look young")
}
}
✅ 关键要点总结:
- ✅ 使用 return &Person{...} 让房间函数输出角色数据;
- ✅ 主函数通过 var p *Person 统一接收,并做 nil 判断保障健壮性;
- ✅ 所有消费函数(avatar/appearance)必须接受 *Person 参数,不可省略星号;
- ❌ 避免在函数内声明同名局部变量企图“泄露”到外部——Go 无全局隐式变量;
- ? 可进一步封装为 Room 类型或使用接口抽象房间行为,提升可扩展性。
这样设计不仅解决了数据传递问题,还使程序职责清晰、易于测试与维护。










