2022-08-17:以下go语言代码输出什么?A:运行时 panic;B:32;C:编译错误;D:0。 package main func main() { var x *struct {
2022-08-17:以下go语言代码输出什么?A:运行时 panic;B:32;C:编译错误;D:0。
package main
func main() {
var x *struct {
s [][32]byte
}
println(len(x.s[99]))
}
答案选B。这道题很多人会选A,包括我也选A了。
1.选A的理由
定义一个结构体类型指针变量,即 x 是一个指针,指针类型是一个匿名结构体。很显然,x 的值是 nil,所以报panic也是很自然的。
println(x.s)
// panic: runtime error: invalid memory address or nil pointer dereference。
2.但这里为什么答案不是A呢?
原因在于len函数。
len 函数是一个内置类型,什么意思?就是由编译器实现的。它的参数可以接收多种类型,有泛型的味道。
func len(v Type) int
关于它的说明,标准库文档有说明:
内建函数 len 返回 v 的长度,这取决于具体类型:
数组:v 中元素的数量
数组指针:*v 中元素的数量(v 为 nil 时 panic)
切片、map:v 中元素的数量;若 v 为nil,len(v) 即为零
字符串:v 中字节的数量
通道:通道缓存中队列(未读取)元素的数量;若 v 为 nil,len(v) 即为零
光这个解释,还不够全面,len 函数还有其他一些特殊的点。这要看 Go 语言规范。
在规范中,有一节是关于 len 和 cap 的[1]。有如下几个要点:
返回结果总是 int;
返回结果有可能是常量;
有时对函数参数不求值,即编译期确定返回值;
2、3 点解释下。(规范中有说明)
如果 len 或 cap 的函数参数 v 是字符串常量,则返回值是一个常量。
如果 v 的类型是数组或指向数组的指针,且表达式 v 没有包含 channel 接收或(非常量)函数调用,则返回值也是一个常量。这种情况下,不会对 v 进行求值(即编译期就能确定)。否则返回值不是常量,且会对 v 进行求值(即得运行时确定)。
这一点是这道题的关键。
首先,x.s[99] 的类型是 [32]byte,它是一个数组,且表达式 x.s[99] 没有包含 channel 接收也不是函数调用,因此不会对 x.s[99] 进行求值,不求值自然不会 panic(想不明白?可以想成没有解引用操作)。也就是说,编译器能够在编译阶段分析出 x.s[99] 的类型是 [32]byte,且不需要对 x.s[99] 求值,因此直接返回数组的长度,即 32。
3.其他类似情况
类似这样不求值的情况还有没有?还真有。比如下面的代码:
var testdata *struct {
a *[7]int
}
for i, _ := range testdata.a {
fmt.Println(i)
}
同样不会 panic,原理和上面的类似,在 Go 语言规范有说明[2]。
“range” 子句中右侧的表达式被称为 range 表达式 ,它可以是数组、数组的指针、切片、字符串、map或是允许接收操作 的 channel。range 表达式会在开始此循环前被求值一次,但有一个例外:当存在最多一个迭代变量且 len(x) 是常量时,range 表达式是不被求值的。
所以上面代码中 testdata.a 不会被求值,因为 len(testdata.a) 是常量。
但如果改为这样:
var testdata *struct {
a *[7]int
}
for i, j := range testdata.a {
fmt.Println(i, j)
}
就会 panic。

2022-08-17:以下go语言代码输出什么?A:运行时 panic;B:32;C:编译错误;D:0。 package main func main() { var x *struct {的更多相关文章
- C 语言实例 - 输出当前文件执行代码
C 语言实例 - 输出当前文件执行代码 输出当前文件执行代码,__FILE__ 为当前执行的文件常量. 实例 #include <stdio.h> int main() { FILE *f ...
- VC++6.0环境下调试c语言代码的方法和步骤_附图
1.C语言程序四步开发步骤 (1)编辑.可以用任何一种编辑软件将在纸上编写好的C语言程序输入计算机,并将C语言源程序文件*.c以纯文本文件形式保存在计算机的磁盘上(不能设置字体.字号等). (2)编译 ...
- 统计学习导论之R语言应用(三):线性回归R语言代码实战
统计学习导论(ISLR) 参考资料 The Elements of Statistical Learning An Introduction to Statistical Learning 统计学习导 ...
- 使用highlight.js高亮静态页面的语言代码
显示静态的代码其实html的pre标签基本可以满足需求了,至少不会将换行的文本显示成一堆字符串. 不过能使静态的文本能高亮显示,倒更炫酷一点.其实很简单的,引入highlight.js包,可以使用cd ...
- 浅析VS2010反汇编 VS 反汇编方法及常用汇编指令介绍 VS2015使用技巧 调试-反汇编 查看C语言代码对应的汇编代码
浅析VS2010反汇编 2015年07月25日 21:53:11 阅读数:4374 第一篇 1. 如何进行反汇编 在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息.如下图所示. ...
- 在Golang中使用C语言代码实例
转自:http://www.jb51.net/article/56720.htm cgo 使得在 Golang 中可以使用 C 代码. Hello World 为了有一个较为直观的了解,我们来看一个简 ...
- Java后台调用gcc编译C语言代码
想做一个能够在线编译代码运行的平台,Java和SQL已经支持了,因为是用Java写的后台,所以Java和SQL挺容易就实现了,做到支持C的时候就卡住了,网上搜了一下这种帖子好像很少. 我采取的办法是就 ...
- 机器学习十大算法总览(含Python3.X和R语言代码)
引言 一监督学习 二无监督学习 三强化学习 四通用机器学习算法列表 线性回归Linear Regression 逻辑回归Logistic Regression 决策树Decision Tree 支持向 ...
- 模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径
模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...
- go语言系列--输出正弦函数
实验所用到的标准库和包 库与包之间的理解可以类比成:数据库种的库和表 库名 作用 image 常见图形格式的访问及生成 log 日志记录库 math 数学库 os 操作系统平台不依赖平台操作封装 查看 ...
随机推荐
- c# Visual Studio|There is no editor available for ***,make sure the application for the file type(.vb) is installed问题解决方法
这个问题出现在在使用VS编码当中,电脑意外关机,导致的文件的缺失或者损坏. 使用反编译软件(如:ILSpy)对编译后的 .EXE文件进行反编译,在翻遍的结果中将相关代码拷贝至目标路径下,替换所需文件. ...
- layui tree 未命名 所遇到的坑
由于传入类型不对,需要传入object类型,我传入的是String类型,所以出现了 一堆未命名, 在控制台输出查看,是一模一样的,困扰了我一下午,再次感谢老哥 参考自:https://www.cnbl ...
- JConsole连接远程Java进程
1.Java进程启动新增如下参数 java -Djava.rmi.server.hostname=118.89.68.13 #远程服务器ip,即本机ip -Dcom.sun.management.jm ...
- [转]常见的视频编码详解 Cinepak Codec by Radius
AVI所采用的压缩算法并无统一的标准.也就是说,同样是以AVI为后缀的视频文件,其采用的压缩算法可能不同,需要相应的解压软件才能识别和回放该AVI文件.除了Microsoft公司之外,其他公司也推出了 ...
- 剑指 offer 第 2 天
第 2 天 链表(简单) 剑指 Offer 06. 从尾到头打印链表 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 示例 1: 输入:head = [1,3,2] 输出:[2, ...
- offsetX与offsetLeft
offsetX:鼠标指针距离当前绑定元素左侧距离,他并不是相对于带有定位的父盒子的x,y坐标, 记住了,很多博客都解释错了 offsetLeft,offsetTop 相对于最近的祖先定位元素.
- Win系统下实现任意exe静态免杀
Win系统下实现任意exe静态免杀?很简单 近几天用C++写了个远控,发现生成出来的exe都会被识别,可能是有人和我写的代码差不多,细想了一下,可能只有静态过不了,动态应该是可以过的,毕竟不可能巧到流 ...
- Flask框架cbv的写法、请求与响应、请求扩展、session源码分析、闪现
本篇文章将会详细讲在flask框架如何写cbv.请求与响应.请求扩展.session源码分析.闪现等知识点. 目录 一.flask写CBV 二.请求与响应 三.session 四.闪现flash 五. ...
- Android Banner - ViewPager 02
Android Banner - ViewPager 02 现在来给viewpager实现的banenr加上自动轮播 自动轮播的原理,使用handler的延迟消息来实现. 自动轮播实现如下内容 开始轮 ...
- 人工智能 deepface 换脸技术 学习
介绍 Deepface是一个轻量级的python人脸识别和人脸属性分析(年龄.性别.情感和种族)框架.它是一种混合人脸识别框架缠绕状态的最先进的模型:VGG-Face,Google FaceNet,O ...