Go 语言核心 36 讲
郝林
《Go 并发编程实战》作者,前轻松筹大数据负责人
79610 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 55 讲
Go 语言核心 36 讲
15
15
1.0x
00:00/00:00
登录|注册

04 | 程序实体的那些事儿(上)

新旧变量混合
短变量声明
同一代码块
类型相同
重构示例
不影响运行效率
代码重构容易
程序灵活性提升
重声明条件
语法糖
示例
好处
短变量声明
var关键字
接口
结构体
函数
常量
变量
变量重声明
类型推断
声明变量的方式
程序实体
外层代码块中的变量重名意味着什么?
Go语言特性介绍
程序演化路径
思考题
Go语言编程
程序实体的那些事儿

该思维导图由 AI 生成,仅供参考

我已经为你打开了 Go 语言编程之门,并向你展示了“程序从初建到拆分,再到模块化”的基本演化路径。
一个编程老手让程序完成基本演化,可能也就需要几十分钟甚至十几分钟,因为他们一开始就会把车开到模块化编程的道路上。我相信,等你真正理解了这个过程之后,也会驾轻就熟的。
上述套路是通用的,不是只适用于 Go 语言。但从本篇开始,我会开始向你介绍 Go 语言中的各种特性以及相应的编程方法和思想。
我在讲解那两种源码文件基本编写方法的时候,声明和使用了一些程序实体。你也许已经若有所觉,也许还在云里雾里。没关系,我现在就与你一起梳理这方面的重点。
还记得吗?Go 语言中的程序实体包括变量、常量、函数、结构体和接口。 Go 语言是静态类型的编程语言,所以我们在声明变量或常量的时候,都需要指定它们的类型,或者给予足够的信息,这样才可以让 Go 语言能够推导出它们的类型。
在 Go 语言中,变量的类型可以是其预定义的那些类型,也可以是程序自定义的函数、结构体或接口。常量的合法类型不多,只能是那些 Go 语言预定义的基本类型。它的声明方式也更简单一些。
好了,下面这个简单的问题你需要了解一下。

问题:声明变量有几种方式?

先看段代码。
package main
import (
"flag"
"fmt"
)
func main() {
var name string // [1]
flag.StringVar(&name, "name", "everyone", "The greeting object.") // [2]
flag.Parse()
fmt.Printf("Hello, %v!\n", name)
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了Go语言中的程序实体,包括变量、常量、函数、结构体和接口的声明和使用方法。通过讲解类型推断和短变量声明,详细解释了类型推断的好处以及对程序灵活性的提升。文章通过示例代码和问题解析,帮助读者了解了Go语言中声明变量的多种方式,以及类型推断在代码重构中的作用。此外,文章还介绍了变量的重声明,包括其含义、前提条件和重要性。总结了使用关键字`var`和短变量声明对变量的“声明并赋值”的基本方法,以及它们各自的特点和适用场景。最后,提出了一个思考题,引发读者思考与当前变量重名的外层代码块中的变量意味着什么。整篇文章通过简洁清晰的语言,帮助读者快速理解Go语言中程序实体的基本概念和特点,为后续深入学习和实践奠定了基础。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 语言核心 36 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(54)

  • 最新
  • 精选
  • Shawn
    置顶
    当前变量覆盖外层变量
    2018-08-17
    1
    66
  • Andy Chen
    “你可以随意改变getTheFlag函数的内部实现及其返回结果的类型,而不用修改main函数中的任何代码。”这个说法只在你给定的例子下面成立,事实上main函数的代码已经假设getTheFlag会返回字符串,因为它在用返回值,如果getTheFlag一开始是返回某种结构体指针,main使用了这个指针指向的一系列成员,然后你再改getTheFlag返回类型看看。类型推断已经深入大多数语言,包括c++,C#,等等,但它没办法解决所谓的使用者不需要改变任何代码就能进行重构

    作者回复: 重构有很多种,有大有小啊。

    2018-08-17
    2
    25
  • xiaolonghuster
    按照老师的demo,不能获取命令参数,只能得到默认值,改成下面这样可以:我用的是1.10.3版本,是不是版本问题 func main() { var name = getTheFlag() flag.Parse() fmt.Printf("Hello, %v!\n", *name) } func getTheFlag() *string { return flag.String("name", "everybody", "The greeting object.") }

    作者回复: 这里确实是写错了,你改的很对,谢谢指正!我想邀请你进入本专栏的微信讨论群。你知道入群方法吗?

    2018-08-17
    9
    13
  • 冰激凌的眼泪
    var name = *flag.String("name", "everyone", "The greeting object.") 这一句是不是导致name是个副本,parse后也不会变?请郝老师确认一下

    作者回复: 已经修正了。

    2018-08-18
    8
  • 钟鑫
    对于变量重声明我有一点疑问,我程序中尝试了,对于重声明的变量其地址是一样的,这个还算重声明吗?

    作者回复: 当然算,这是两码事。

    2019-11-13
    4
  • loser
    你好,不知道还能看到这个评论不。我在学习gopsutil时遇到一个问题。cpu包下有cpu_linux.go,cpu_windows.go等文件,这两个文件中都有Times()函数,在windows平台我有鼠标点击Times查看引用时,他自动跳转到cpu_windows.go中去了,这是什么原因,为啥没跳入cpu_linux中去。如果看到了,请帮我解惑下,万分感谢

    作者回复: 名称中带有 _<操作系统代号> 都属于根据操作系统定制的源码文件。你在 win 下面当然应该查看 cpu_windows.go 。另外,这种点击的跳转逻辑应该是代码编辑器插件或者IDE的行为,不关Go语言本身的事。

    2020-06-08
    3
  • 小苹果
    老师,puzzlers\article4\q1\demo7.go里面有个隐式错误。 var name = *flag.String("name", "everyone", "The greeting object.") 这种方法输出的结果永远是 Hello, everyone!,不论 -name 后面是什么。 正确的应该是: func main() { // 方式1。 var name = flag.String("name", "everyone", "The greeting object.") flag.Parse() fmt.Printf("Hello, %v!\n", *name) }

    作者回复: 嗯,看到了,这确实是个问题,当初是为了不改动其他代码。我想想怎么调整一下。谢谢。

    2019-05-04
    3
  • charlesgogo01
    name := *flag.string()这儿为啥会有*,本来返回应该是个变量值,这样是传递地址吗?

    作者回复: Go里面没有传递地址这种说法。*在这里是取值操作符。

    2018-09-03
    2
  • 小小笑儿
    思考题: 内部作用域的变量会覆盖外部作用域的变量,是声明一个新的变量而不是重声明,重声明只在同一个作用域生效。 可以使用go vet -shadow显示这一类错误。

    作者回复: vet会提示有隐患,重声明和可重名变量都容易让人产生迷惑,这也是也讲到它们的原因。哦,对了,课重名变量会在下一篇讲。

    2018-08-17
    2
  • escray
    类型推断(编程语言在编译期自动解释表达类型)最早是在 C# 里面看到的,作为一种语法糖,用起来感觉很好。 表达式类型就是对表达式进行求值后得到结果的类型 An expression specifies the computation of a value by applying operators and functions to operands. Go 语言的类型推断提升了程序的灵活性,便于重构,同时没有损失程序的性能(在编译期确定类型)。 Go 语言的类型推断只用于变量或常量的初始化。 对于思考题,如果与当前变量重名的是外层代码块中的变量,那么相当于是在内层代码块中的一个新的变量,可以与外层同名变量不同类型。 a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. 看到答案中提到“可重名变量”,那么还有“不可重名变量”么?

    作者回复: 可以说,同一个代码块中的变量就是“不可重名变量”。(“同一个代码块中的重名变量”在Go语言中是不合法的)

    2021-05-03
    1
收起评论
显示
设置
留言
54
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部