GO

一、基础

1.变量

强类型语言

  • 声明单个变量

    Go语言在声明变量时,自动对变量对应的内存进行初始化操作,不同于C语言的默认不初始化。

  • 声明变量并初始化

  • 类型推断

  • 声明多个变量

    var(
        a int
        b string
        c float32
    )
    
  • 简短声明

    语法:name := initialvalue
    注意::= 操作符的左边至少有一个变量是尚未声明的

  • 多重赋值

    用于交换两个值的内容

    var a int = 100
    var b int = 200
    a,b = b,a
    
  • 匿名变量(Lua中叫哑元变量)

    _ ,使用匿名变量是,只需要在变量声明的位置用下划线(_)替换即可

2.数据类型

  • bool

    bool类型无法参与数值运算,,也无法与其他类型进行转换

  • 数字

    • int8 , int16 , int32 , int64 , int(常用整形)
    • uint8 , unit16 ,unit32 , unit64 , unit (无符号,最小0)
    • float32 , float64 (浮点)
    • complex64 , complex128 (复数,几乎不会用到吧?)
    • byte (同 unit8)
    • rune (同 int32)
  • string

    Go中字符串作为基础数据类型出现。

    • 多行字符串

    使用反引号 ”`“实现
    使用反引号包含的字符串,所有转义符均无效,文本将原样输出。(用处应该不会很大)

    • 字符串实现基于UTF-8
    • 字符

    字符有一下两种:
    一种是unit8类型(byte),代表一个ASCII码字符。
    一种是rune类型,代表一个UTF-8字符。rune实际上就是一个int32。

    另外,UTF-8和Unicode的区别:  
    Unicode是字符集,类似ASCII字符集,为每个字符分配一个唯一的ID。UFT-8是编码规则,将Unicode的字符ID以某种方式进行编码。
    广义的Unicode是指一个标准。
    

    在 Printf 方法中,使用 %T 格式说明符(Format Specifier),可以打印出变量的类型。Go 的 unsafe 包提供了一个 Sizeof 函数,该函数接收变量并返回它的字节大小。unsafe 包应该小心使用,因为使用 unsafe 包可能会带来可移植性问题。不过出于本教程的目的,我们是可以使用的。
    格式说明符 %T 用于打印类型,而 %d 用于打印字节大小

    可以使用 "+" 拼接

    • 计算字符串的长度

    Go语言内建函数 len() 可以获取字符串的字符数。结果为ASCII码个数,汉子等其他字符集会出错。
    UTF-8包提供 RuneCountInString() 函数,可以获取Unicode字符个数。

    使用:
    len(string)
    utf8.RuneCountInString(string)
    
    • 遍历字符串

    遍历ASCII码字符使用for循环即可,直接用下表取。
    遍历Unicode使用 for range

    使用:
    for i := 0 ; i < len(str) ; i++{
        fmt.Printf("%c %d",str[i],str[i])       
    }
    
    for _,s : = range str{
        fmt.Printf("%c %d",s,s)
    }
    
    • 获取字符串的某一段字符(Substring)

    strings.Index 正向搜索子字符串
    strings.LastIndex 反向搜索子字符串
    搜索其实位置可以使用切片偏移制作

    tracer := "撒夺魂幡,宝宝,baba"
    comma := strings.Index(tracer, ",")
    pos := strings.Index(tracer[comma:],"宝宝")
    
    fmt.Println(comma,pos,tracer[comma+pos:])
    
    
    • 修改字符串

    Go语言中字符串无法直接修改每一个字符元素,只能通过重新构造新的字符串赋值给原来的字符串来实现。实际上是将字符串转为 []byte 进行修改。
    string 和 []byte 可以相互强制类型转换。

    • 连接字符串

    可以使用 "+" 进行连接,也可以使用StringBuilder进行高效的字符串连接。

    string1 := "abd"
    string2 := "def"
    stringBuilder.WriteString(string1)
    stringBuilder.WriteStrign(string2)
    
    fmt.Println(stringBuilder.String())
    
    • 格式化

      延续C语言

    动词 功能
    %v 值的本来值
    %+v 在%v的基础上对结构体字段名和值进行展开
    %#v Go语言语法格式的值
    %T Go语言语法格式的类型和值
    %% %本体
    %b 二进制
    %o 八进制
    %d 十进制
    %x 十六进制
    %X 十六进制、字母大写
    %U Unicode字符集
    %f 浮点数
    %p 指针,十六进制
    • Base64编码

    Base64编码是常见的对8比特字节码的编码方式之一。
    Go语言的标准库自带了Base64编码算法。

    import {
        "encoding/base64"
    }
    
    message := "Hello World"
    //编码
    encodeMessage := base64.StdEncoding.EncodeToString([]byte(message))
    //解码
    data , err := base64.StdEncoding.DecodeString(encodeMessage)
    
  • 切片(能动态分配的空间)

切片是一个拥有相同类型元素的可变长度的序列。

声明:var name []T
T代表切片元素的类型,可以是int、float、bool、map、slice等

  • 指针

每个变量都拥有地址,指针的值就是地址。同C语言,"*"代表指针取值,"&"作为取地址操作符。取地址操作符"&"和取值操作符"*"是一对互补操作符。

通过指针不仅可以取值,还可以修改值。”*“操作符的根本意义是操作指针指向的变量。
*a = *b,代表是将b指针指向的值赋值给a指针指向的值。
而,若a,b都是指针类型,使用 b,a=a,b ,赋值结果并不会影响a,b分别指向的值。

创建指针的方式:new(T)
eg:str := new(string) *str = "nanjing" new()
函数可以创建一个对应的类型的指针,创建过程会自动分配内存。(并没有想到有啥应用场景,可以直接使用变量完成事情,为啥要用指针变量?性能更高?)

  • 类型转换

Go 有着非常严格的强类型特征。Go 没有自动类型提升或类型转换。
使用 T(value) 进行类型转换。

eg: var j float64 = float64(i)

  • 类型别名(Type Alias)

类型别名语法:type NewInt = int
类型定义语法:type NewInt int
类型定义会形成一个新的类型,类型别名只会在代码中存在,编译完成时,将不存在。
非本地类型不能自定义方法(只能为当前包中的类型定义)

3.常量

表达式:const name = "value"

Go 的类型策略不允许将一种类型的变量赋值给另一种类型的变量,别名也不行。

数字常量可以在表达式中自由混合和匹配,只有当它们被分配给变量或者在需要类型的代码中的任何地方使用时

  • 枚举(一组常量值)

    Go语言中现在没有枚举,可以使用常量配合 iota 模拟出枚举

    type Weapon int
    const(
        Arrow Weapon = iota
        Blower
        Rifle
        Shuriken
    )
    
    fmt.Println(Arrow,Blower)
    
    //使用枚举类型
    var weapon Weapon = Arrow
    
    

    iota不仅只能生成每次增加1的枚举,也可以实现一些强大的枚举

    const (
        //左位移操作
        FlagNone = 1 << iota
        FlagRed
        FlagGreen
        FlagBlue
    )
    //十进制
    fmt.Printf("%d %d %d",FlagRed,FlagGreen,FlagBlue)
    //二进制
    fmt.Printf("%b %b %b",FlagRed,FlagGreen,FlagBlue)
    
    输出结果:
    2 4 8 
    10 100 1000
    
    
  • 枚举转字符串

    type ChipType int 
    const(
        None ChipType = iota
        CPU
        GPU
    )
    
    func (c ChipType) String() string{
        switch c{
            case None:
                return "None"
            case CPU:
                return "CPU"
            case GPU:
                return "GPU"
        }
        return "N/A"
    }
    
    //当这个类型需要显示为字符串时,Go语言会自动寻找 String() 方法并进行调用。
    fmt.Printf("%s %d", CPU , CPU)
    
    输出:
    CPU 1
    
    

5.包

  包用于组织 Go 源代码,提供了更好的可重用性与可读性。由于包提供了代码的封装,因此使得 Go 应用程序易于维护。

  • main 函数和 main 包

  • 创建自定义包

    属于某一个包的源文件都应该放置于一个单独命名的文件夹里。按照 Go 的惯例,应该用包名命名该文件夹。
    包中函数名首字母大写。

  • 导入自定义包

    import (  
        "fmt"
        "geometry/rectangle" // 导入自定义包
    )
    
  • 导出名字

在 Go 中,任何以大写字母开头的变量或者函数都是被导出的名字。其它包只能访问被导出的函数和变量。相当于Public和Private方法

  • init函数

    所有包都可以包含一个 init 函数。init 函数可用于执行初始化任务,也可用于在开始执行之前验证程序的正确性。
    包的初始化顺序如下:

    首先初始化包级别(Package Level)的变量(有点全局变量的意思)
    紧接着调用 init 函数。包可以有多个 init 函数(在一个文件或分布于多个文件中),它们按照编译器解析它们的顺序进行调用。

    如果一个包导入了另一个包,会先初始化被导入的包,尽管一个包可能会被导入多次,但是它只会被初始化一次。

    import (  
    "fmt"
    "geometry/rectangle" // 导入自定义包
    "log"
    )
    /*
     * 1. 包级别变量
    */
    var rectLen, rectWidth float64 = 6, 7 
    
    /*
    *2. init 函数会检查长和宽是否大于0
    */
    func init() {  
         println("main package initialized")
         if rectLen < 0 {
             log.Fatal("length is less than zero")
          }
       if rectWidth < 0 {
            log.Fatal("width is less than zero")
       }
    }
    
    func main() {  
        fmt.Println("Geometrical shape properties")
        fmt.Printf("area of rectangle %.2f\n",rectangle.Area(rectLen, rectWidth))
        fmt.Printf("diagonal of the rectangle %.2f",rectangle.Diagonal(rectLen, rectWidth))
    }
    
  • 使用空白标识符
    导入了包,却不在代码中使用它,这在 Go 中是非法的。然而,在程序开发的活跃阶段,又常常会先导入包,而暂不使用它。遇到这种情况就可以使用空白标识符 _。

    package main
    import (  
      "geometry/rectangle" 
    )
    var _ = rectangle.Area // 错误屏蔽器
    func main() {
    }
    

有时候我们导入一个包,只是为了确保它进行了初始化,而无需使用包中的任何函数或变量。(用于一些配置文件的引入?)

```
package main 
import (
     _ "geometry/rectangle" 
)
func main() {
}
```
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • 1.安装 https://studygolang.com/dl 2.使用vscode编辑器安装go插件 3.go语...
    go含羞草阅读 1,497评论 0 6
  • 官方网站:https://golang.org/标准库文档:https://golang.org/pkg/在线编码...
    技术学习阅读 2,312评论 2 39
  • Go语言数据类型 Go语言本质是用C语言编写的一套高级开发语言, 所以Go语言中的数据类型大部分都是由C语言演变而...
    极客江南阅读 892评论 0 6
  • fmt格式化字符串 格式:%[旗标][宽度][.精度][arg索引]动词旗标有以下几种:+: 对于数值类型总是输出...
    皮皮v阅读 1,071评论 0 3
  • (稻盛哲学学习会)打卡第25天 姓名:柳琳 部门:开发部 组别:待定 【知~学习】 阅读《活法》第二章节 与外国交...
    木木_be35阅读 213评论 0 0