V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
ztao8607
V2EX  ›  Go 编程语言

脱掉 Golang 的第一层衣裳 golang 入坑系列

  •  
  •   ztao8607 · 2017-11-20 16:25:45 +08:00 · 2904 次点击
    这是一个创建于 2349 天前的主题,其中的信息可能已经有所发展或是发生改变。

    读前必读:同样的内容,同样的 markdown. gitbook 显示一切正常。 博客园基本凑合。V2EX 显示的惨不忍睹,本想着再修改一下,但思来想去还是算了吧。 就这样吧。 外行看热闹,内行看门道。 如果真的合您胃口,您应该会去gitbook查看原文。 如果不合胃口,改了也是白改。 所以就这样吧,还好,难看的地方不是很多。

    海鳖曾欺井内蛙,大鹏张翅绕天涯。强中更有强中手,莫向人前满自夸。

    各位看官,现在开始脱衣裳。你不用脱,自个衣裳要穿好了,别脱下来。我们是来学 Golang 的,不是来耍流氓的。本节,我们来正式的学习 Golang。如果前面几节一路看下来,能看到自己写的 golang 代码正常运行,自然好事一件。但不能就以为学会 golang 了。学任何东西,都不能自满。强中自有强中手,人外自有计高人。如果看不到也不要灰心,我只是做了个普及,好比正餐前的开胃菜。合口就多吃,不合口就等着下面的大餐。

    花来两朵,各表一枝。Party 现在正式开始。

    Golang 的程序结构

    一个完整且典型的 Golang 程序包含以下几部分:

    • 包声明(Package Declaration)
    • 引入依赖包(Import Packages)
    • 逻辑函数(Function)
    • 过程变量(Variables)
    • 语句和表达式(Statements and Expressions)
    • 注释(Comments)

    麻雀虽小,五脏俱全。 再小的耗子也是耗子,我们把之前的 hello god 再次搬上来,逐一对照一下:

    1. package main
    
    2. import "fmt"
    
    3. func main() {
    4.     /* This is my first sample program. */
    5.     var str = "Hello God, My Golang.\n"
    6.     fmt.Printf(str)
    7. }
    

    第一行的 package main,叫做包声明。包,又名 package,是 golang 的名字。一个人没名字,还能比划一下多高多胖。但程序代码没名字,鬼才知道怎么调用呢。 所以每个 Golang 程序必须要有名字。 这个名字就是 package 后面的单词。 上面的代码中定义这个包叫做 main。

    第二行就是引入的依赖包。 看到 fmt 这么短的名字,应该想到这是一个标准包。如果忘记三类包如何区分了,😑,大哥,上点心别走神,返回上节重新温习。在 Golang 中引入依赖包,就用"import 包名"的格式引入。一个程序不可能引入一个包吧? 引入的包多了怎么办? 有两种方法:

    方法一:逐行 import
    import fmt
    import log
    import net/http
    

    难不难看?丑不丑? 肯定难看,所以基本上,都会写成下面这样:

    import (
        "io/ioutil"
        "log"
        "time"
    )
    

    还丑? 那没辙了,凑合看吧。基本上各种 IDE,在格式化 golang 代码时,都会格式化成第二种。所以建议直接用第二种,反正你用了第一种,IDE 格式化时也会给你变成第二种。

    从第三行到第七行,就是函数的范围了。Golang 的函数格式是: func 函数名(参数...){}。Golang 本身就支持函数式编程,所以有名无名无所谓。但如果现在就开始说函数式编程,你不看晕,我都快写晕了。所以现在先不提这事,留到后面再说。

    在函数名称上面,Golang 有个特殊规定。首字母是大写的,表示允许其他包可以直接调用。 如果首字母是小写的,则不允许其他包调用。简而言之,首字母大写,表示允许其他包可见。而小写,就表示函数不可见。而 main 函数是个特例,它就叫做 main。因为 mian 表示整个函数的入口,所以 golang 替你规定好了,所有的函数入口一律叫做 mian,写别的,对不起不认识。

    **最后还要记住一点,main 函数一定在 main 包里。 **试试把 package main 改成 test,go build 之后看看有没有可执行文件?一定没有。

    第四行是注释。 和其它语言一样,支持 /**/注释,也支持 //注释。 注释很重要,好记性不如烂笔头。写好注释,指不定哪天会挽救你那可怜的职业生涯,尤其是在线上出现 bug,大老板站在你身后,而自己又不知道为啥要写这一行代码时。想想那个场景,就不寒而栗。

    第五行,是传说中的变量声明。Golang 声明变量,也有两种方式。

    --- 我是声明方式一 ---
    var 变量名 变量类型
    
    --- 我是声明方式二 ---
    变量名 := 变量类型
    

    第一种使用最多的情况是,声明基本类型。例如 string,boolean,int 等等。比如声明一个字符串: var str string。str 是变量名,string 是变量类型。然后声明之后,还给它赋值,str = "I am Lilei, what's your name?"。 但这样看起来啰嗦,不简洁。所以都会这么写:

    var str = "I am Lilei, what's your name?"
    

    基本类型都可以这么去赋值,而第二种多用在复杂类型上,例如声明一个结构体实例:

    obj1 := Object{
        xxxx:xxxx,
        yyyy:yyyy,
    }
    

    现在还没说到结构体,所以上面这一段可以略过不看。

    这两种声明方式没有强制规定,必须用在什么场景中。还是那句话,高兴就好,怎么写的嗨,就怎么写。规矩是死的,人是活的。

    但别看没有强制规定,就用混了。Golang 中通过":="来表示新变量。也就是说,如果你用了 var 来声明,就直接使用"="。 如果你不想写 var,就使用":="。变量声明就这么点小提示,开心的去玩吧。 写错写多了,也就记住了。😄

    第六行,是语句。 也称之为表达式。其实声明变量也属于语句的一种,说白了,函数就是由语句组成的。 和其他程序不一样的是,Golang 的语句是通过换行符来断句的。也就是一行是一个语句,有的语言是通过";"这一类的符号来断句的。 但 Golang 是通过换行符,刚转过来的同学,适应适应吧。

    好,我们就把上面的小 Demo 解剖完了,但衣裳还没拔完,继续"流氓"。

    Golang 的基本语法

    上来,先说 Golang 中哪些是不允许你瞎命名的,也就是 Golang 的保留关键字.

    | Golang 关键字 | | :---: |

    | break | default | func | interface | select | | :--- | :--- | :--- | :--- | :--- | | case | defer | Go | map | Struct | | chan | else | Goto | package | Switch | | const | fallthrough | if | range | Type | | continue | for | import | return | Var |

    表里面的单词,都是 Golang 独家享有的,你写程序时无论是变量还是函数都不能和上面的单词重名。

    再往后就是 Golang 中空格的使用,golang 通过空格来识别语义,例如:

    var age int
    

    这三个单词之间通过空格隔开,golang 再编译时,就可以识别出 var,age 和 int。就能明白你的意图。如果你中间没有空格,那编译器都傻眼了。所以在写代码时,记住正确使用空格。

    如果命名时避开了关键字,是不是就可以随便命名了?当然不是的,Golang 已经规定了标识符的命名规则。Golang 规定:

    一个标识符必须以字母 a 到 Z 或 a 到 Z 或一个下划线开头,后面跟着零或更多的字母、下划线和数字(0 到 9)。
    

    为了便于理解和免于鄙视,老老实实的命名,别用那么多稀奇古怪的名字。

    今天楼上一直在装修,凿墙之声,此起彼伏,声声入耳无法逃避。忽高忽低,捉摸不定。搞得心情也是十五只水桶,甚为不爽。为了保证写作质量,就先写到这里。

    欲知后事如何,点个 star,订阅一下。

    28 条回复    2017-11-23 09:31:04 +08:00
    owenliang
        1
    owenliang  
       2017-11-20 16:31:53 +08:00
    ztao8607
        2
    ztao8607  
    OP
       2017-11-20 16:35:18 +08:00
    每种语言都有官方教程,每种语言也都有各种第三方教程。 官方教程固然权威,但不可否认的是很多人不愿去翻看官方教程。 所以才萌生了用自己的风格来写一篇教程的想法。
    zjsxwc
        3
    zjsxwc  
       2017-11-20 16:45:13 +08:00
    ztao8607
        4
    ztao8607  
    OP
       2017-11-20 16:57:23 +08:00
    @zjsxwc 不同的人有不同的角度,我在按照我的理解来写一份入门级的教程。 不同的书有不同的读者,选择多了,对生态圈来说不是一件好事么... 您说呢?
    v2orz
        5
    v2orz  
       2017-11-20 16:58:51 +08:00
    目前还在学,但是 the-way-to-go 总感觉哪里不通畅的样子,可能是由于我看的中文版吧
    所以支持一下楼主
    ztao8607
        6
    ztao8607  
    OP
       2017-11-20 17:02:11 +08:00
    @v2orz 谢谢支持。 也希望我写的能对你有所帮助。最新的文章都在 gitbook 中,https://andy-zhangtao.gitbooks.io/golang/content。 博客园和 V2EX 也会不定期的同步(主要是排版不如 gitbook 好看)。还是那句话,能帮助到别人,就算是没别写。
    tempdban
        7
    tempdban  
       2017-11-20 17:30:37 +08:00   ❤️ 1
    因为 面 表示整个函数的入口,所以 golang 替你规定好了,所有的函数入口一律叫做所有的函数入口一律叫做 面
    huawuya
        8
    huawuya  
       2017-11-20 17:35:50 +08:00
    不错,支持楼主
    CreSim
        9
    CreSim  
       2017-11-20 17:37:26 +08:00 via Android
    支持,据说 go 是现在最值得学的语言。
    ztao8607
        10
    ztao8607  
    OP
       2017-11-20 17:37:51 +08:00
    @tempdban 谢谢指出。 原文已修改。 再次感谢
    ztao8607
        11
    ztao8607  
    OP
       2017-11-20 17:43:45 +08:00
    @huawuya 谢谢支持。
    ztao8607
        12
    ztao8607  
    OP
       2017-11-20 17:46:17 +08:00
    @CreSim 说"最"个人感觉有些言过其实。但目前国内使用 golang 的场景和公司的确日益增多。 编程语言只是一门工具,只有根据特定的业务场景才能选择出最合适的编程语言。 但作为程序员来说,技多不压身,多学点东西总归不是一件坏事。:-D
    neighbads
        13
    neighbads  
       2017-11-20 17:55:21 +08:00
    感觉不错哦。。。打算入坑了。
    fivestrong
        14
    fivestrong  
       2017-11-20 18:16:11 +08:00 via Android
    正在学,支持楼主。
    Devin
        15
    Devin  
       2017-11-20 18:41:01 +08:00 via iPhone
    貌似最近 V2 多了不少 golang 的帖子
    loading
        16
    loading  
       2017-11-20 18:52:16 +08:00 via Android
    learnyinx 更推荐
    yushiro
        17
    yushiro  
       2017-11-20 19:50:56 +08:00 via iPhone
    支持一下,写的都是重点啊!
    JokerHuang
        18
    JokerHuang  
       2017-11-20 20:27:07 +08:00
    如果我没记错,变量声明是有强制规定的,全局变量必须使用 var 声明。
    前段时间用 golang 做了个项目,整理了两份脑图感觉细节点非常多,期待楼主慢慢更新
    scnace
        19
    scnace  
       2017-11-20 20:31:14 +08:00 via Android
    可能很多人会忽略 Go 自己的 wiki https://github.com/golang/go/wiki
    ztao8607
        20
    ztao8607  
    OP
       2017-11-20 21:20:39 +08:00 via Android
    @JokerHuang 好像是没有全局变量使用 var 的限制吧?明天我确认一下。如果其它同学能帮忙确认的话,感激不尽。
    ztao8607
        21
    ztao8607  
    OP
       2017-11-20 21:23:07 +08:00 via Android
    @scnace 深有同感,我也经常读 go 官方 blog。里面提供了很多语言细节,对学习 golang 有很大的帮助
    Kilerd
        22
    Kilerd  
       2017-11-20 21:23:23 +08:00
    我选择教程的原则有亮点
    - 英文优先,中文次之
    - 言简意赅者优先,我不是来看废话的
    SuperMild
        23
    SuperMild  
       2017-11-20 21:27:27 +08:00
    @ztao8607 官方 blog 的文章质量真是非常高,有不少是还是 Rob Pike 大牛亲自写的,真正做到了深入浅出。
    ztao8607
        24
    ztao8607  
    OP
       2017-11-20 21:33:03 +08:00 via Android
    @Kilerd 粗茶淡饭,酸甜苦辣。八仙过海,各显神通。每人有每人的学习方法,每人也有每人的喜好。至废话不废话,因人而异吧。我不会说此教程会普惠大众,只要能给希望学习 golang 的同学带来哪怕丁点儿的帮助,这就够了。
    54007
        25
    54007  
       2017-11-20 23:30:03 +08:00
    js 是最好的语言
    metorm
        26
    metorm  
       2017-11-20 23:36:38 +08:00 via Android
    支持一下。不过有几个 main 写成了 mian
    yanjinbin
        27
    yanjinbin  
       2017-11-21 00:49:16 +08:00 via iPhone
    能不能少写这些同质文章
    lepig
        28
    lepig  
       2017-11-23 09:31:04 +08:00
    @yanjinbin 为什么呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2211 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 00:31 · PVG 08:31 · LAX 17:31 · JFK 20:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.