开发者社区> 宇宙之壹粟> 正文

Go 语言入门很简单--技巧和窍门(Tips and Tricks)

简介: Go 语言入门很简单--技巧和窍门(Tips and Tricks)
+关注继续查看

本节将随着时间的推移而增长,但主要目标是分享一些有经验的开发人员在一段时间内发现的技巧。希望这些技巧能让新用户更快地提高工作效率。

image.png

140个字符提示

[宇宙之一粟翻译]:

  • leave your object oriented brain at home. Embrace the interface. @mikegehard

别想着面向对象了,拥抱接口吧。

  • Learn to do things the Go way, don’t try to force your language idioms into Go. @DrNic

学习用 Go 语言的方式做事,不要试图把你的语言习性强加给Go。

  • It’s better to over do it with using interfaces than use too few of them. @evanphx

接口使用宜多不宜少。

  • Embrace the language: simplicity, concurrency, and composition. @francesc

拥抱这门语言:简单、并发和组合。

阅读他们在golang.org网站上的所有精彩文档。

多多使用 gofmt

阅读大量的源码。

  • Learn and become familiar with tools and utilities, or create your own! They are as vital to your success as knowing the language. @coreyprak

学习并熟悉工具和实用程序,或创建自己的工具和实用程序!它们对您的成功与了解语言一样重要

额外导入包的方法

还有其他几种导入包的方法。我们将在以下示例中使用 fmt 包:

  • import format "fmt" : 创建 fmt 的别名. 然后在所有使用 fmt 包内容的地方使用 format. 而不是 fmt.format.Println("Hello,World")
  • import . "fmt" : 多了个点号 . ,这种方式允许直接访问包的内容,无需在其前面加上 fmt
  • import _ "fmt" - 如果未使用 fmt ,则抑制与 fmt  相关的编译器警告,如果有则执行初始化函数。 fmt  的其余部分无法访问。

有关更多详细信息,请参阅 此博客文章。

goimports

Goimports 是一种更新 Go 导入行、添加缺失行和删除未引用行的工具。

它的作用与 gofmt(插入式替换)相同,但除了代码格式之外,还修复了导入。

代码组织

Go是一种非常简单的编程语言,但首先是开发人员最难的事情是如何组织代码。由于许多原因,轨道变得流行,并且脚手架是其中之一。它给出了新的开发人员清晰的指示和地方,以便将其代码和成语遵循。

在某种程度上,Go 通过为开发人员提供很棒的工具(如 go fmt)以及不会编译未使用的变量或未使用的导入语句的严格编译器来做同样的事情。

自定义构造函数

我经常听到的一个问题是我应该什么时候使用像 NewJob  这样的自定义构造函数。我的答案是,在大多数情况下你不需要。但是,每当您需要在初始化时间设置值并且您有某种默认值时,它都是构造函数的好候选者。在上面的示例中,添加构造函数会产生很多意义,因此我们可以设置默认记录器。

package main

import (
    "log"
    "os"
)

type Job struct {
    Command string
    *log.Logger
}

func NewJob(command string) *Job {
    return &Job{command, log.New(os.Stderr, "Job: ", log.Ldate)}
}

func main() {
    NewJob("demo").Print("starting now...")
}

重构包中的代码

参见这篇关于 重构 Go 代码的博客文章,第一部分讨论包组织。

集合

您可能希望找到一种方法来从集合中提取唯一值。用其他语言,您通常具有不允许重复的集数据结构。Go 没有内置的,但它不太难以实现(由于缺乏泛型,你需要为大多数类型做到这一点,这可能是麻烦的)。

// UniqStr returns a copy if the passed slice with only unique string results.
func UniqStr(col []string) []string {
    m := map[string]struct{}{}
    for _, v := range col {
        if _, ok := m[v]; !ok {
            m[v] = struct{}{}
        }
    }
    list := make([]string, len(m))

    i := 0
    for v := range m {
        list[i] = v
        i++
    }
    return list
}

我使用了一些有趣的技巧。首先,空结构体的映射:

  m := map[string]struct{}{}

我们创建了一个映射,键是我们想要唯一的值,关联的值并不重要,所以它可以是任何东西。例如:

m := map[string]bool{}

然而,我选择了一个空结构,因为它会像布尔值一样快,但不会分配那么多内存。

第二个技巧可以看得更清楚一点:

f _, ok := m[v]; !ok {
  m[v] = struct{}{}
}

我们在这里所做的,只是检查映射 m 中是否有与键 v 关联的值,我们不关心值本身,但是如果我们知道我们没有值,那么我们添加一个。

一旦我们有了一个带有唯一键的映射,我们就可以将它们提取到一个新的字符串切片中并返回结果。

下面是这个函数的测试,如你所见,我使用了一个表测试,这是运行单元测试的惯用 Go 方式:

func TestUniqStr(t *testing.T) {

    data := []struct{ in, out []string }{
        {[]string{}, []string{}},
        {[]string{"", "", ""}, []string{""}},
        {[]string{"a", "a"}, []string{"a"}},
        {[]string{"a", "b", "a"}, []string{"a", "b"}},
        {[]string{"a", "b", "a", "b"}, []string{"a", "b"}},
        {[]string{"a", "b", "b", "a", "b"}, []string{"a", "b"}},
        {[]string{"a", "a", "b", "b", "a", "b"}, []string{"a", "b"}},
        {[]string{"a", "b", "c", "a", "b", "c"}, []string{"a", "b", "c"}},
    }

    for _, exp := range data {
        res := UniqStr(exp.in)
        if !reflect.DeepEqual(res, exp.out) {
            t.Fatalf("%q didn't match %q\n", res, exp.out)
        }
    }

}

依赖包管理

不幸的是,Go 没有自带依赖包管理系统。可能是因为它起源于 C 文化,包没有版本化,也没有解决显式的版本依赖问题。

挑战是,如果您的项目上有多个开发人员,则希望所有这些都在依赖项的同一版本上。您的依赖项也可能有自己的依赖性,并且您希望确保一切顺利。当您使用不同版本的相同依赖项时,它会产生甚至欺骗者。这通常是  CI 环境中的情况。

Go 社区针对这些问题提出了许多不同的解决方案。但对我来说,没有一个是真正好的,所以在  Splice 我们找到了最简单的工作解决方案: https://github.com/pote/gpm

Gpm 是一个简单的 bash 脚本,我们最终对其进行了 一些修改,以便我们可以将脚本放到每个 repo 中。 bash 脚本使用名为 Godeps 的自定义文件,其中列出了要安装的软件包。

当切换到不同的项目时,我们运行项目 gpm 脚本来下拉或设置每个包的正确版本。

在我们的 CI 环境中,我们在运行测试套件之前将 GOPATH 设置为项目特定的文件夹,因此项目之间不会共享包。

善用错误

错误是 Go 中非常重要的模式,起初,新开发人员对返回值和错误的函数数量感到惊讶。

Go 没有您可能在其他编程语言中看到的异常概念。 Go 确实有一种叫做 panic 的东西,但正如它的名字所暗示的那样,它们真的很特别,不应该被拯救(也就是说,它们可以)。

首先,Go的错误处理似乎繁琐和重复,但迅速成为我们思考方式的一部分。而不是创建泡起来且可能或可能不会处理或通过更高的异常,而是错误是响应的一部分,并且旨在由呼叫者处理。每当函数可能会生成错误时,其响应应包含错误参数。

Go 团队的 Andrew Gerrand 写了一篇关于错误的很棒的 博客文章,我强烈建议你阅读它。

Effective Go section on errors


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13886 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18645 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
25057 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20365 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
13456 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
9686 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
13913 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
14713 0
+关注
宇宙之壹粟
目前就职于外企软件工程师;InfoQ签约作者;51CTO首席体验官;后端开拓者;头发比想法多的研究僧; 混迹于江湖,江湖却没有我的影子 热爱技术,专注于后端全栈,轻易不换岗 拒绝内卷,工作于软件工程师,弹性不加班 热衷分享,执着于阅读写作,佛系不水文
120
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载