使用gofmt格式化代码

对于一门编程语言来说,代码格式化是最容易引起争议的一个问题,不同的开发者可能会有不同的编码风格和习惯,但是如果所有开发者都能使用同一种格式来编写代码,开发者就可以将宝贵的时间专注在语言要解决的问题上。 gofmt 介绍 Golang 的开发团队制定了统一的官方代码风格,并且推出了 gofmt 工具(gofmt 或 go fmt)来帮助开发者格式化他们的代码到统一的风格。gofmt 是一个 cli 程序,会优先读取标准输入,如果传入了文件路径的话,会格式化这个文件,如果传入一个目录,会格式化目录中所有.go 文件,如果不传参数,会格式化当前目录下的所有.go 文件。 gofmt 默认不对代码进行简化,使用-s 参数可以开启简化代码功能,具体来说会进行如下的转换: 去除数组、切片、Map 初始化时不必要的类型声明: 如下形式的切片表达式: []T{T{}, T{}} 将被简化为: []T{{}, {}} 去除数组切片操作时不必要的索引指定 如下形式的切片表达式: s[a:len(s)] 将被简化为: s[a:] 去除迭代时非必要的变量赋值 如下形式的迭代: for x, _ = range v {...} 将被简化为: for x = range v {...} 如下形式的迭代: for _ = range v {...} 将被简化为: for range v {...} gofmt 命令参数列表如下: usage: gofmt [flags] [path ...] -cpuprofile string write cpu profile to this file -d display diffs instead of rewriting files -e report all errors (not just the first 10 on different lines) -l list files whose formatting differs from gofmt's -r string rewrite rule (e.g., 'a[b:len(a)] -> a[b:]') -s simplify code -w write result to (source) file instead of stdout 可以看到,gofmt 命令还支持自定义的重写规则,使用-r 参数,按照 pattern -> replacement 的格式传入规则。 ...

七月 17, 2018 · 2 分钟 · Zhiya

搭建Kubernetes集群时DNS无法解析问题的处理过程

问题描述 在搭建 Kubernetes 集群过程中,安装了 kube-dns 插件后,运行一个 ubuntu 容器,发现容器内无法解析集群外域名,一开始可以解析集群内域名,一段时间后也无法解析集群内域名。 $ nslookup kubernetes.default Server: 10.99.0.2 Address 1: 10.99.0.2 kube-dns.kube-system.svc.cluster.local nslookup: can't resolve 'kubernetes.default' 排查过程 在排查问题前,先思考一下 Kubernetes 集群中的 DNS 解析过程,在安装好 kube-dns 的集群中,普通 Pod 的 dnsPolicy 属性是默认值 ClusterFirst,也就是会指向集群内部的 DNS 服务器,kube-dns 负责解析集群内部的域名,kube-dns Pod 的 dnsPolicy 值是 Default,意思是从所在 Node 继承 DNS 服务器,对于无法解析的外部域名,kube-dns 会继续向集群外部的 dns 进行查询,过程如图。 Ubuntu 容器是一个普通的 Pod,在 Linux 系统中,/etc/resolv.conf 是存储 DNS 服务器的文件,普通 Pod 的/etc/resolv.conf 文件应该存储的是 kube-dns 的 Service IP。 nameserver 10.99.0.2 # 这里存储的是kube-dns的Service IP search default.svc.cluster.local. svc.cluster.local. cluster.local. options ndots:5 查看后发现/etc/resolv.conf 文件中存储的是 kube-dns 的 Service IP,证明这一步没有问题,接下来查看一下 kube-dns 的 Pod,先进入 kube-dns 的 Pod 中检查一下/etc/resolv.conf 文件,这里存储的应该是集群外部的 DNS 服务器地址,查看后发现,这里存储的地址是 127.0.0.53,进一步查看 kube-dns Pod 的 log,发现出现了非常多的 i/o timeout 错误。 ...

七月 15, 2018 · 3 分钟 · Zhiya

Golang环境安装和依赖管理

2015 年,Go 1.5 加入了一个试验性的 vendor 机制(到 2016 年的 Go 1.6 版变为默认开启),vendor 机制就是在项目中加入了 vendor 文件夹,用于存放依赖,这样就可以将不同项目的依赖隔离开。 Golang 一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。Golang 提供了方便的安装包,支持 Windows、Linux、Mac 系统。 下载安装包 Golang 的官网是https://golang.org/,如果官网打不开,可以访问https://golang.google.cn/这个域名。在官网点击 Download Go 会进入下载页,可以看到这里提供了针对各个系统的安装包,也提供了源码,可以下载源码编译安装。 下载运行安装包后,在 terminal 中执行 go env 命令,如果出现下面的输出说明已经安装成功。 GOROOT 与 GOPATH 仔细看上面的输出,会发现其中有一个 GOPATH,又有一个 GOROOT,那么到底哪个才是 Golang 的运行环境呢。 首先访问一下 GOROOT 这个路径,会发现其中包含 bin、lib 等文件夹。GOROOT 就是 Golang 的安装路径,其中包含 Golang 编译、工具、标准库等,在安装后就会存在。 和 GOROOT 不同,GOPATH 是工作空间路径,从 go 1.8 开始,如果 GOPATH 没有被设置,会有一个默认值,在 Unix 上为$HOME/go,在 Windows 上为%USERPROFILE%/go,当调用 go build 时,它会在 GOPATH 中寻找源码。访问一下 GOPATH 这个路径,会发现其中只有 pkg、bin、src 三个文件夹,并且里面基本是空的,这是一个约定的目录结构,src 文件夹用来存放源码、pkg 存放编译后生成的文件,bin 存放编译后生成的可执行文件。项目代码需要在 GOPATH/src 路径下。 ...

七月 10, 2018 · 1 分钟 · Zhiya

你所不知道的Python | 函数参数的演进之路

函数参数处理机制是 Python 中一个非常重要的知识点,随着 Python 的演进,参数处理机制的灵活性和丰富性也在不断增加,使得我们不仅可以写出简化的代码,也能处理复杂的调用。 关键字参数 调用时指定参数的名称,且与函数声明时的参数名称一致。 关键字参数是 Python 函数中最基础也最常见的,我们写一个记账的函数,参数是需要记录的时间和金额。 def add_record(date, amount): print('date:', date, 'amount:', amount) 这里的 amount 参数就是一个关键字参数,关键字参数支持两种调用方式: 位置调用 关键字调用 位置调用,就是按参数的位置进行调用,例如传入两个参数,第一个是字符串 2018-07-06,第二个是整数 10,那么这两个参数会被分别赋予 date 和 amount 变量,如果顺序反过来,则这两个参数分别赋予 amount 和 date 变量。 add_record('2018-07-06', 10) # 输出date: 2018-07-06 amount: 10 add_record(10, '2018-07-06') # 输出date: 10 amount: 2018-07-06 关键字调用,可以忽略参数顺序,直接指定参数。 add_record(amount=10, date='2018-07-06') # 虽然参数顺序反了,但是使用了关键字调用,所以依然输出date: 2018-07-06 amount: 10 仅限关键字参数 我们定义一个 Person 类,并实现它的__init__方法 class Person(object): def __init__(self, name, age, gender, height, weight): self._name = name self._age = age self._gender = gender self._height = height self._weight = weight 当初始化这个类的时候,我们可以使用关键字调用,也可以使用位置调用。 ...

七月 10, 2018 · 2 分钟 · Zhiya

你所不知道的Python | 字符串连接的秘密

字符串连接,就是将 2 个或以上的字符串合并成一个,看上去连接字符串是一个非常基础的小问题,但是在 Python 中,我们可以用多种方式实现字符串的连接,稍有不慎就有可能因为选择不当而给程序带来性能损失。 方法 1:加号连接 很多语言都支持使用加号连接字符串,Python 也不例外,只需要简单的将 2 个或多个字符串相加就可以完成拼接。 a = 'Python' b = '私房菜' r = a + b # 输出'Python私房菜' 方法 2:使用%操作符 在 Python 2.6 以前,%操作符是唯一一种格式化字符串的方法,它也可以用于连接字符串。 a = 'Python' b = '私房菜' r = '%s%s' % (a, b) # 输出'Python私房菜' 方法 3:使用 format 方法 format 方法是 Python 2.6 中出现的一种代替%操作符的字符串格式化方法,同样可以用来连接字符串。 a = 'Python' b = '私房菜' r = '{}{}'.format(a, b) 方法 4:使用 f-string Python 3.6 中引入了 Formatted String Literals(字面量格式化字符串),简称 f-string,f-string 是%操作符和 format 方法的进化版,使用 f-string 连接字符串的方法和使用%操作符、format 方法类似。 a = 'Python' b = '私房菜' r = f'{a}{b}' 方法 5:使用 str.join()方法 字符串有一个内置方法 join,其参数是一个序列类型,例如数组或者元组等。 a = 'Python' b = '私房菜' r = ''.join([a, b]) 对比测试 既然连接字符串有这么多方法,那么使用时到底选择哪种呢?我们从代码可读性和性能两个层面来评估一下上面 5 种方法。 ...

六月 28, 2018 · 1 分钟 · Zhiya