现在这个系列,已经开始两极分化了。 点赞的认为风格轻松,看着不困。反之,就有人嫌写的罗里吧嗦,上纲上线。所以善意提醒,里面不只是技术语言,还有段子。专心看技术的,千万别点!别怪我没提醒!差点忘说,版权没有,转载随意,别删邮箱(ztao8607@gmail.com)

我都承认文章标题起的是越来越扯淡了。从开始的"安装Golang","解密Golang工程结构"这一类中规中矩的标题,现在已经慢慢进化成了"维多利亚的秘密","我们是80后"这一类相当无技术含义的标题。说实话,我都快编不下去了。

来一段歌词,看能否勾起你的回忆:

敢在景阳岗上穿虎皮装。 在高粱地里套母狼。左手拿刀(挲),右手拿枪(啪)。他就是蟑螂中的绝对偶像。敢去皇宫里翻遍御膳房。也能到你家里去扫荡。就算鞋板儿拍下敌敌畏夺命。死也要死个酷了毙。

早上无意听到这段<特务小强>的歌词,感觉一下就回到了上大学的那个时光。 不知道即将步入青年后半段的人,是不是都喜欢怀旧。我的80后记忆还停留在老北京酸奶,北京方便面,镭射录像厅,世嘉游戏机。除了二八大杠的自行车,就是路边的游戏机房。 那会的网吧还都是局域网在玩红警,CS刚出来名称换做反恐精英。沙丘还能找到,但玩最多的当属金庸群侠传。

就是在这些游戏当中,让我对计算机充满了好奇,也憧憬着如果有一天我能自己写个游戏该有多好。理想一直存在,可现实已被摧残。看着身边的90后,00后已经逐渐扛起行业的大梁,只能对着他们感叹一句:

在青年的队列里面,我们已经排在了队尾。好好干,总有一天,让我们在队尾汇合。

感慨已完,开始正题。在维密一节中,我们讲到了函数的使用方式,本节聊一聊变量作用域的事情。

变量作用域

综合之前的描述,我们可以得出一个结论:任何一种语言,都存在变量。 并由此可知,只要有变量,就会有变量作用域。 好比每个国家都有法律,而每个法律都有适用范围。最简单的例子就是中国法律管不了美国的事。所以本节聊的就是变量作用域的那些事。

在Golang当中,变量分为三类:

  • 本地局部变量
  • 全局变量
  • 参数变量

本地局部变量,顾名思义只能在本地生效的变量。在Golang当中,本地的定义是按照函数或者语义块来区分的。只要在一个函数中定义的变量,或者在一个语义块中定义的变量都是本地变量。

函数定义容易理解,例如下面的例子:

func Test(){
str := "This is a local var"
....
}

str是定义在Test函数内部的变量,因此就是本地变量。下面则是一个语义块的示例:

func Test(){
for{
str := "This is a local var in block"
...
}
}

可以看到str是定义在for这个语义块内部的,因此str也是一个本地变量。 那么本地变量的作用域在哪里呢? 哪国的法律管哪国的事,变量定义在哪里,就在当前范围内生效。

在示例一中,str定义在Test函数中,因此在Test函数内部,str都畅通无阻。出了Test函数以后,就无法使用str变量了。 同理可知,在示例二中,str定义在for循环内部,因此只能在for内部使用str。一旦出了for循环,同样也无法再访问str。

是的,你一定会问,如果出现重名变量怎么办? 首先我建议,尽量不要出现重名。 尽量不要自己给自己挖坑。 但非挖不可,那Golang会按照当前作用域优先的原则,替换变量。例如下面的例子:

package main

import (
"fmt"
) func main() {
str := "local var"
if true {
str := "block var"
fmt.Println(str)
}
fmt.Println(str)
}

在main函数中定义了一个str变量,然后再if语义块中也定义了一个str变量。按照当前作用域优先的原则,当程序运行到if内部之后,if中的str会替代外部的str变量值。 所以首先输出"block var'。 当出了if范围之后,里面的str已经失效,外部无法访问。因此最后会使用main函数作用域的str变量,所以输出"local var"。

因此最终输出

block var
local var

还是那句话,代码最好别用花哨的东西,写的清清楚楚明明白白最好。一般别挖坑,要挖就挖大坑。

与本地变量相对应的就是全局变量。 只要是在函数外部定义的都属于全局变量。例如下面的例子:

var g int

func main(){
a := 10
b := 10
g = a+b
...
}

注意千万不能g := a+b。 因为我们说过变量的声明方式有“var"和”:="两种。如果不小心写了个" g:=a+b"。虽然对最终的结果没有影响,但意思已经改变了,变成了在main函数中重新创建了一个g变量。

虽说全局变量也是变量,但全局变量的声明只能通过var来实现。例如下面是合法的:

var g int
或者
var g = 40 func main(){
...
}

而下面则是非法的:

g := 40

func main(){
}

不要问什么了,规定就是规定,遵守就好。全局变量的作用域当然就是全局了,但这个全局指的是package内。 在当前package内都可以随意访问,如果想让其他package访问,那么需要遵从Golang的原则,首字母大写。这样才能让其他Package访问到。

如果遇到同名问题怎么样? Golang同样会按照作用域优先原则处理,例如下面的例子:

var g = 40

func main(){
a := 10
b := 10
g := a+b
...
}

注意,在main函数中,同样存在一个g变量,但这个g变量是通过":="声明出来的。 因此按照作用域优先原则,此时此刻的g=30。全局的g=40。 如果这方面感觉不理解,写两句代码,run一下立马见分晓。

最后一种是参数变量。参数变量是一种特殊的变量,既不属于本地变量,也不属于全局变量(有点废话了,如果属于就不会单列出来了)。 其介于两者之间,作用域是函数范围,先看下面的例子:

func Test(str string){
i := 10
....
}

通过上面的分析可知,i属于本地变量,而str则属于参数变量。 与本地变量相同的一点时,其作用域相同,都是函数范围。 但不同的地方有两处:

  1. 参数变量赋值是在外部完成的,联想一下<维密>那节,我们讲解函数时,如何给参数赋值。就可以知道赋值的动作是在调用时完成的。
  2. 参数变量可以声明之后不使用。这点尤为明显,如果声明了一个本地变量,但自始至终都没有用到。编译时会提示删除这个变量。而参数变量,无论函数内部有没有用到,都不会提示。

所以可以向对待本地局部变量那样对待参数变量,本地局部变量适用的法则,参数变量同样适用。

写完变量,看了看内容不多。因此再多写一点,反正没有出版社约稿,也就不会受到大纲的约束,想到哪里写到哪里。

下面进入Golang常用类型的使用场景

String

在每种编程开发语言种,字符串都是内置的一种数据类型,原因就是因为它太重要了。前面也提到过一嘴,Golang的字符串本质是字符数组([]byte)。

创建字符串很简单,上面用过很多次了:

var greeting = "Hello world!"
或者
greeting := "Hello world!"

Golang默认使用UTF-8编码处理字符串,所以不用担心汉字编码的问题。作为一种现代语言,Golang不限制字符串的长度,理论上只要内存有多大,字符串就可以有多大。但还是本着"no zuo no die"的理念,别放那么长的字符串,没人喜欢在代码中读小说。

Golang专门有一个strings的package(https://golang.org/pkg/strings/ )来处理各种常见的string问题。例如查找,拼接,判断,大小写转换和替换,拷贝等等常见功能。

String很重要,但真的没什么可讲的。绝大多数的问题都可以通过strings库来解决,如果有问题,自行看一下库文档吧。 虽说是本系列是个入门教程,但事无巨细都写完,很不现实。 如果写完了,那就变成Golang中文文档了。

所以String这一小节,记住有一个strings库就够了。

如果你是80后,真心感叹你还能有如此强的求知欲。 如果你非80后,好好珍惜眼前的日子吧。 该玩就玩,该挥霍就挥霍。别等哪天将发际线熬到了耳后,才后悔当初没有好好泡妹子。

我们是80后 golang入坑系列的更多相关文章

  1. 我们是80后 golang入坑系统

    现在这个系列,已经开始两极分化了. 点赞的认为风格轻松,看着不困.反之,就有人嫌写的罗里吧嗦,上纲上线.所以善意提醒,里面不只是技术语言,还有段子.专心看技术的,千万别点!别怪我没提醒!差点忘说,版权 ...

  2. 入坑第二式 golang入坑系列

    史前必读: 这是入坑系列的第二式,如果错过了第一式,可以去gitbook( https://andy-zhangtao.gitbooks.io/golang/content/ )点个回放,看个重播.因 ...

  3. 初生牛犊不怕虎 golang入坑系列

    读前必读,下面所有内容都是来自这里. 放到这里的目的,就是为了比对一下,哪里的读者多.平心而论,同样的Markdown,博客园排版真心X看,怎么瞅怎么X看.(X := '难' || X :='耐' | ...

  4. 维多利亚的秘密 golang入坑系列

    原文在gitbook,字字原创,版权没有,转载随意. 在写本文的前一天,2017维密在上海开始了. 为了纪念屌丝界的盛世,特为本节起名维多利亚的秘密.现在的社会,要想出名只有抓眼球.所以写份技术文章, ...

  5. 准备冲锋 golang入坑系列

    史前摘要: 本来想写读前必读,但连续几篇博文都写读前必读,感觉就没有了新意. 所以换成史前摘要,反正是一个意思. 此摘要的目的仍然是提醒点击而来的同学,本系列最新文章在这里.放到博客园的目的是为了方便 ...

  6. 分水岭 golang入坑系列

    第三式开篇语有些负面, 所以这里就不贴了.有兴趣的自己可以去看看 https://andy-zhangtao.gitbooks.io/golang/content/ .怒发冲冠,意气之作.看完就完了, ...

  7. 崩溃 golang入坑系列

    早上(11.30)收到邮件,Vultr东京机房网络故障.当时搭建SS时,考虑到了机房故障.所以特意分出了日本和香港两条线路.但千算万算,忘记数据库还在东京机房中. 现在网络故障,SS服务器无法读取数据 ...

  8. SEO是件贼有意思的事情 golang入坑系列

    这两天迷上了SEO.真心看不起百度的竞价排名,但作为一个商业网站,赚钱是一件无可厚非的事情.只做活雷锋,没有大金主是做不长的.做完功课后,发现百度和google的SEO策略又不相同,几乎是无法通用.百 ...

  9. 坐忘峰 golang入坑系列

    读前必读: 本文写于20日,首发于gitbook. 迟到的是日期,没变的是内容. 点击进入 https://andy-zhangtao.gitbooks.io/golang/content/ 可以看到 ...

随机推荐

  1. FirstLetterUtil

    package cn.edu.hbcf.common.utils; public class FirstLetterUtil { private static int BEGIN = 45217; p ...

  2. FlashBuilder 4.6序列号破解

    1424-4827-8874-7387-0243-7331 1424-4938-3077-5736-3940-5640 具体步骤如下: 1.到Adobe官网下载FlashBuilder 4.6,有简体 ...

  3. 第二百二十九节,jQuery EasyUI,后台管理界面---后台登录

    jQuery EasyUI,后台管理界面---后台登录 登录原理图 一,login.php,登录界面 <!DOCTYPE html> <html> <head> & ...

  4. <!>贴图/音乐

    <img src=图片位址>贴图 <img src=图片位址 width=’180’>设定图片宽度 <img src=图片位址 height=’30’>设定图片高度 ...

  5. Android开发人员必须掌握的10 个开发工具+应该深入学习的10个开源应用项目

    一.Android开发人员必须掌握的10 个开发工具 Android SDK 本身包含很多帮助开发人员设计.开发.测试和发布 Android 应用的工具,在本文中,我们将讨论 10 个最常用的工具. ...

  6. Effective JavaScript Item 55 接受配置对象作为函数參数

    接受配置对象作为函数參数 尽管保持函数接受的參数的顺序非常重要,可是当函数可以接受的參数达到一定数量时.也会让用户非常头疼: var alert = new Alert(100, 75, 300, 2 ...

  7. EF提供的3中查询方式

    1. Linq to Entities using (TestEntities te = new TestEntities()) { var user = from a in te.User wher ...

  8. jQery 操作CSS

    jQuery操作CSS也是很方便的,咱先看看这几个常用的方法: addClass():向一个元素添加一个或者多个类. removeClass():从一个元素中删除一个类或多个类. toggleClas ...

  9. 两天学会DirectX 3D之第二天

    提要 前几天非常easy地跑了一个DirectX 9 程序,以为DirectX就那么绘制,事实证明有点Naive了. 之前的那个程序最多也就是个固定流水线的东西. 可是今天要用DirectX11来写一 ...

  10. django用户认证系统——注册3

    用户注册就是创建用户对象,将用户的个人信息保存到数据库里.回顾一下 Django 的 MVT 经典开发流程,对用户注册功能来说,首先创建用户模型(M),这一步我们已经完成了.编写注册视图函数(V),并 ...