欢迎加入GolangRoadmap,一个年轻的GO开发者社区https://www.golangroadmap.com/,目前是邀请制注册,注册码:Gopher-1035-0722,已开放GO内推,GO面试,GO宝典,GO返利等栏目

我们在 for-range 循环和映射中提过几次空白标识符。 空白标识符可被赋予或声明为任何类型的任何值,而其值会被无害地丢弃。它有点像Unix中的 /dev/null 文件:它表示只写的值,在需要变量但不需要实际值的地方用作占位符。 我们在前面已经见过它的用法了。

多个参数赋值中的空白标识符

for range 循环中对空表标识符的用法是一种具体情况,更一般的情况即为多个参数赋值。
若某次赋值需要匹配多个左值,但其中某个变量不会被程序使用, 那么用空白标识符来代替该变量可避免创建无用的变量,并能清楚地表明该值将被丢弃。 例如,当调用某个函数时,它会返回一个值和一个错误,但只有错误很重要, 那么可使用空白标识符来丢弃无关的值。

if _, err := os.Stat(path); os.IsNotExist(err) {fmt.Printf("%s does not exist\n", path)
}

你偶尔会看见为忽略错误而丢弃错误值的代码,这是种糟糕的实践。请务必检查错误返回, 它们会提供错误的理由。

// 很糟糕的代码!若路径不存在,它就会崩溃。
fi, _ := os.Stat(path)
if fi.IsDir() {fmt.Printf("%s is a directory\n", path)
}

未使用的导入和变量

若导入某个包或声明某个变量而不使用它就会产生错误。未使用的包会让程序膨胀并拖慢编译速度, 而已初始化但未使用的变量不仅会浪费计算能力,还有可能暗藏着更大的Bug。 然而在程序开发过程中,经常会产生未使用的导入和变量。虽然以后会用到它们, 但为了完成编译又不得不删除它们才行,这很让人烦恼。空白标识符就能提供一个工作空间。

这个写了一半的程序有两个未使用的导入(fmt 和 io)以及一个未使用的变量(fd),因此它不能编译, 但若到目前为止代码还是正确的,我们还是很乐意看到它们的。

package mainimport ("fmt""io""log""os"
)func main() {fd, err := os.Open("test.go")if err != nil {log.Fatal(err)}// TODO: use fd.
}

要让编译器停止关于未使用导入的包,需要空白标识符来引用已导入包中的符号。 同样,将未使用的变量 fd 赋予空白标识符也能关闭未使用变量错误。 该程序的以下版本可以编译。

package mainimport ("fmt""io""log""os"
)var _ = fmt.Printf  // 用于调试,结束时删除。
var _ io.Reader    // 用于调试,结束时删除。func main() {fd, err := os.Open("test.go")if err != nil {log.Fatal(err)}// TODO: use fd._ = fd
}

按照惯例,我们应在导入并加以注释后,再使全局声明导入错误静默,这样可以让它们更易找到, 并作为以后清理它的提醒。

为辅助作用而导入

像前例中 fmt 或 io 这种未使用的导入总应在最后被使用或移除: 空白赋值会将代码标识为工作正在进行中。但有时导入某个包只是为了其辅助作用, 而没有任何明确的使用。例如,在 net/http/pprof 包的 init 函数中记录了HTTP处理程序的调试信息。它有个可导出的API, 但大部分客户端只需要该处理程序的记录和通过Web页面访问数据。只为了其辅助作用来导入该包, 只需将包重命名为空白标识符:

import _ "net/http/pprof"

这种导入格式能明确表示该包是为其辅助作用而导入的,因为没有其它使用该包的可能: 在此文件中,它没有名字。(若它有名字而我们没有使用,编译器就会拒绝该程序。)

接口检查

就像我们在前面接口中讨论的那样, 一个类型无需显式地声明它实现了某个接口。取而代之,该类型只要实现了某个接口的方法, 其实就实现了该接口。在实践中,大部分接口转换都是静态的,因此会在编译时检测。 例如,将一个 *os.File 传入一个预期的 io.Reader 函数将不会被编译, 除非 *os.File 实现了 io.Reader 接口。

尽管有些接口检查会在运行时进行。encoding/json 包中就有个实例它定义了一个 Marshaler 接口。当JSON编码器接收到一个实现了该接口的值,那么该编码器就会调用该值的编组方法, 将其转换为JSON,而非进行标准的类型转换。 编码器在运行时通过类型断言检查其属性,就像这样:

m, ok := val.(json.Marshaler)

若只需要判断某个类型是否是实现了某个接口,而不需要实际使用接口本身 (可能是错误检查部分),就使用空白标识符来忽略类型断言的值:

if _, ok := val.(json.Marshaler); ok {fmt.Printf("value %v of type %T implements json.Marshaler\n", val, val)
}

当需要确保某个包中实现的类型一定满足该接口时,就会遇到这种情况。 若某个类型(例如json.RawMessage) 需要一种自定义的JSON表现时,它应当实现 json.Marshaler, 不过现在没有静态转换可以让编译器去自动验证它。若该类型通过忽略转换失败来满足该接口, 那么JSON编码器仍可工作,但它却不会使用自定义的实现。为确保其实现正确, 可在该包中用空白标识符声明一个全局变量:

var _ json.Marshaler = (*RawMessage)(nil)

在此声明中,我们调用了一个 *RawMessage 转换并将其赋予了 Marshaler,以此来要求 *RawMessage 实现 Marshaler,这时其属性就会在编译时被检测。 若 json.Marshaler 接口被更改,此包将无法通过编译, 而我们则会注意到它需要更新。

在这种结构中出现空白标识符,即表示该声明的存在只是为了类型检查。 不过请不要为满足接口就将它用于任何类型。作为约定, 只有当代码中不存在静态类型转换时才能使用这种声明,毕竟这是种非常罕见的情况。

高效GO语言编程(9)——空白标识符相关推荐

  1. 飞思卡尔单片机编程与c语言,飞思卡尔单片机高效C语言编程(中文)

    高效C语言编程实验,包括:CodeWarrior的使用.中断.数据段的定义.常量数据段.变量.位操作.数组.指针.函数内的自变量.优化方法.Manual Optimization(手工优化).Proc ...

  2. c语言开发移动通信,基于ARM的高效C语言编程

    引言 ARM处理器以其高性能.低功耗.低成本等优势被广泛应用于各种成功的32位嵌入式系统中.提高执行速度和减小代码尺寸是嵌入式软件设计的关键需求.尽管大多数的ARM编译器和调试器都带有性能优化工具,但 ...

  3. 高效GO语言编程-代码注释

    更多免费Golang知识,欢迎加入Go宝典 | GOLANG ROADMAP 邀请码:Gopher-1035-0722 Go 语言支持C风格的块注释 /* */ 和C++风格的行注释 //. 行注释更 ...

  4. 定义变量和常量的规范 c语言,C语言编程规范教材及练习(标识符命名与定义 变量 宏、常量 表的达式).pptx...

    C语言编程规范教材及练习(标识符命名与定义 变量 宏.常量 表的达式) C语言编程规范教材C语言编程规范工作组 201104目录标识符命名与定义 变量宏.常量表达式标识符的命名要清晰原则3.1 标识符 ...

  5. R语言编程的高效方法

    R语言编程的高效方法 R语言编程的高效方法 高效编程之细节知识点 并行计算 1.查看核数 2.可以使用并行计算的场景 3.Parellel 包 R语言编程的高效方法 学习资料来源: datacamp ...

  6. 不同设备如何统一语言编程平台高效开发?本文为你揭秘

    原文:不同设备如何统一语言编程平台高效开发?本文为你揭秘,点击链接查看更多技术内容. 随着数字化时代的发展,手机.平板.PC.电视.智能手表.车机等智能设备的普及率越来越高,但不同设备往往搭载了不同的 ...

  7. 用C语言实现高效嵌入式系统编程

    1引言     随着市场竞争的日趋激烈,要求电子工程师能够在短时间内编写出执行效率高而又可靠的嵌入式系统的执行代码.同时,由于实际系统的日趋复杂,要求所写的代码规范.模块化并便于多个工程师以软件工程的 ...

  8. Go语言编程入门超级指南

    Go语言编程入门超级指南 1.序言 Golang作为一门出身名门望族的编程语言新星,像豆瓣的Redis平台Codis.类Evernote的云笔记leanote等. 1.1 为什么要学习 如果有人说X语 ...

  9. C 语言编程 — 编程规范

    目录 文章目录 目录 前文列表 排版 注释 头文件 函数 标识符命名与定义 变量 宏.常量 代码逻辑 内存操作 日志打印 质量保证 单元测试 断言 安全性 可移植性 参考文档 前文列表 <程序编 ...

最新文章

  1. 可溶于水的机器人见过吗?明胶和糖3D打印而成,现登Science子刊封面
  2. 计算机网络系统中hn是,中南大学计算机网络作业1.pdf
  3. poj 2342 树形DP
  4. 开放课程管理系统(Moodle)的介绍(转)
  5. 面试官重点考察求职者这5项能力
  6. 郁金香商业辅助教程 2016 笔记 11~15
  7. linux 占用缓存前10_Linux安装软件时很多人会遇到这个报错,如何解决?
  8. VB 使用SendMessage枚举文件与目录
  9. Create a Search Scope for a Sharepoint 2010 List or Library
  10. IP归属地查询API
  11. banner.txt
  12. java经纬度转换小数_java经纬度格式转换
  13. MMGG聚焦| Mines of Dalarnia-土地预售在即
  14. php微信支付mch_id参数格式错误,再说一下微信支付踩到的坑 mch_id 参数格式错误...
  15. TFN2.5G传输分析仪FT100-D300S——网络传输搭建维维护
  16. ABAP:多页签的选择屏幕
  17. Lichee_RV学习系列--stream移植
  18. 电脑图片删除怎么找回?快试试这个方法!
  19. php网站iis7.5 session,IIS7/7.5下web.config奇葩的问题(伪静态html无法使用session)
  20. 工作流管理系统开发之十二 同一张表单在流程多节点中流转的权限控件

热门文章

  1. 单服务台排队系统c语言编程,单服务台排队系统建模与仿真研究报告最终版(范文1)...
  2. 寻找hadoop、hive、spark对应版本
  3. 商城电商day13一、订单业务简介
  4. jQuery入门:实用方法(Utility Methods)
  5. c语言的运算符分类ppt,c语言的数据类型、运算符与表达式.ppt
  6. 论文中三线表的生成方法
  7. html特殊字符代码
  8. 【读书笔记】ndss2018_K-Miner_ Uncovering Memory Corruption in Linux
  9. UCM狂热者:从Base方式转移到UCM ClearCase
  10. 弹力弹珠java_Java实力弹弹球实现代码