学习golang的历程——持续更新

Posted zhoulixiansen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习golang的历程——持续更新相关的知识,希望对你有一定的参考价值。

学习一门语言首先hello world

1,首先建立一个目录,新建一个hello.go的文件

package main

import (
   "fmt"
)

func main()  {
   fmt.Println("hello world")
}

2,go run hello.go


jack_zhou@zhoulideMacBook-Pro study % go run hello.go
hello world


上面我们就完成了我们的基础使命。下面我们正式开始入门

在正式进入写代码之前,推荐大家使用JB家族的Goland

在设置中需要注意GOPATH和GOROOT不能写同一个地址,否则会报错:

warning: GOPATH set to GOROOT (/usr/local/go) has no effect

一,入门篇

1,golang语言特性

① 垃圾回收

  1. 内存自动回收,不需要开发人员管理内存
  2. 开发人员只需关注业务实现,降低负担
  3. 只需new分配内存,不需要释放

② 天然并发

  1. 从语言层面支持并发,非常简单
  2. goroute,轻量级线程,创建成千上万个goroute成为可能
  3. 基于CSP(Communicating Sequential Process)模型实现

③ 管道(channel)

  1. 管道,类似unix/linux中的pipe
  2. 多个goroute之间通过channel进行通信
  3. 支持任何类型

④ 多返回值

  1. 定义函数返回类型需要加括号
  2. 返回需要以,作为分隔

⑤ 需要编译

go build + 路径

2,变量的定义:

# 第一种package变量
var (
    a = 1
    b = 2
)
var aa = true

# 第二种非package变量
var a, b int = 1, 2
# 简写
var a,b = 1, "89"
# 精简
a, b := 1, "78"  // 全局不可使用

在上一个例子的基础上写一个加法函数,传入两个变量,返回两个参数之和

package main

import (
    "fmt"
)

func add(a int, b int) int {
    var sum int 
    sum = a + b
    return sum

}

func main()  {
    var c int
    c = add(100, 200)
    fmt.Println("hello world!", c)
}

在上述例子中,我们可以看到,他是没有封号

在定义变量的时候需要指定比变量的类型,定义函数的时候,在()外需要写上返回值的类型

需要注意的是,go不容许定义变量而不使用的情况发生,否则编译的时候就会报错,比如:


c declared and not used


3,包的定义

  • 和Python语言,把相同功能代码放到一个目录中,称之为包(因此,在写代码的时候都需要写package 包名)
  • 包当然支持被其他包的引用
  • main包是用来生成可执行文件,每一个程序有且只能有一个main包
  • 包的主要用途是提高代码的可复用性

4,注意事项

① Go 进行build的时候经常会遇到 can‘t load package

在Goland中配置

技术图片

需要加上Project GOPATH 路径

② Go新建项目默认需要在src下,并且,编译的时候不需要将src路径写入

go默认所有的项目文件都放在src目录下面

在project目录下执行go build go_test/day1/example即可

③ 一般build文件都指定在一个bin目录

go build -o bin/calc go_dev/day1/package_count/main

用 -o 来指定目录bin,文件为calc,编译的是main

5,go的基本类型

① 文件名&关键字&标识符

  • [x] 所有源码以.go结尾

  • [x] 标识符以字母或者下划线开头,大小写敏感(_)

  • [x] _是特殊标识符,用来忽略结果

  • [x] 保留关键字

    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

② Go程序基本结构

  1. 任何一个代码文件隶属于一个包

  2. import 关键字,引用其他包

    import ("fmt")
    import ("os")
    // 通常写为
    import (
     "fmt"
      "os"
    )
  3. Golang 可执行程序,package main,并且有且只有一个main函数入口

  4. 包内函数调用,直接调用

  5. 不同包内调用函数,需要通过包名 + 点 + 函数名进行调用(函数名首字母必须大写)

    package main
    
    import "fmt"
    
    func list(n int) {
       for i := 0; i <= n; i++ {
          fmt.Println("%d+%d=%d
    ", i, n-i, n)
       }
    }
    func main() {
       list(10)
    }
    // 打印循环
  • [x] 注意:在包中可以定义一个init函数,默认会在main执行之前执行

    package calc
    
    var Name string = "jack"
    var Age int = 10
    
    func init() {
       Name = "zhou"
       Age = 100
    }
    // 最终结果是Name为zhou,Age为100
    // 执行顺序 先执行全局变量,在执行init,最后到main

③ 常量和变量

一,常量

  1. 常量使用const修饰,代表永远是只读的,运行期间不能够修改

  2. const只能修饰boolean,number(int相关类型、浮点类型、cpmplex)和string

  3. 语法:const identifier [type] = value,其中type可以省略。

    const b string = "hello world"
    const b = "hello world"
    const Pi = 3.1415926
    const a = 9.3
    const c = getValue() // 错误,因为常量是不可改变的
  4. 单行注释 // 多行注释 /* */(其实和JS的写法一致的)

二,变量

见上方变量的定义

④ 数据类型和操作符

一,数据类型

值类型: 基本数据类型int,float, bool, string以及数组和struct

当值类型需要修改的时候 传入值之前加一个&即可,比如:

modify(a) ---->>> modify(&a)

这样就相当于传入a的内存地址到modify中去

引用类型: 指针,slice,map, chan等都是引用类型

二,操作符

  1. 逻辑操作符

    == 、!=、<=、>=、>、<、!、&&、 ||

    func main() {
       a := 10
       if (a > 2) {
          fmt.Println(a)
       }
    }
  2. 数学操作符

    +、-、*、/ 等等

⑤ 字符串类型

func main()  {
   var str = "hello world
"
   var str1 = `
        窗前明月光,
      地上鞋两双。
      `
   var b byte = 'c'
   fmt.Println(str)
   fmt.Println(str1)
   fmt.Println(b)
   fmt.Printf("%c
", b)
}

go在进行输出的时候是不会改变原有的样式的,对于打印bytes对象,会直接打印对于字符表中的具体位置的

fmt文档:给您放这里啦

例子: 交换两个变量的值

package main

import (
   "fmt"
   _ "os"
)

func swap(a int, b int) {
   tem := a
   a = b
   b = tem
   return
}

func main() {
   first := 100
   second := 200
   swap(first, second)
   fmt.Println(first, second)
}

结果如下:

jack_zhou@zhoulideMacBook-Pro ~ % /Users/jack_zhou/workspace/gospace/project/main ; exit;

100 200


为啥没有产生变化呢?

因为这两个变量属于值类型的,值类型是属于复制拷贝,改的是副本的值,如果需要改就必须传入指针地址。那如何修改呢?

package main

import (
   "fmt"
   _ "os"
)

func swap(a *int, b *int) {
   tem := *a
   *a = *b
   *b = tem
   return
}

func main() {
   first := 100
   second := 200
   swap(&first, &second)  // 传入变量的地址
   fmt.Println(first, second)
}

结果如下:

Last login: Sun Dec 8 22:55:57 on ttys002

jack_zhou@zhoulideMacBook-Pro ~ % /Users/jack_zhou/workspace/gospace/project/main ; exit;

200 100


package main

import (
   "fmt"
   _ "os"
)

func swap(a int, b int) (int, int) {
   tem := a
   a = b
   b = tem
   return a, b
}

func main() {
   first := 100
   second := 200
   first, second = swap(first, second)  // 传入变量的地址
   fmt.Println(first, second)
}

通过返回值的方式也是可以的

最简单的方式是:

package main

import (
   "fmt"
   _ "os"
)

func main() {
   first := 100
   second := 200
   first, second = second, first
   fmt.Println(first, second)
}

写到这突然发现还是Python大法好啊╮( ̄▽ ̄)╭

⑥ 字符串的操作

  1. 直接相加

    package main
    
    import "fmt"
    
    func main()  {
       var str = "hello"
       var str2 = " world"
       str3 := str+str2
       fmt.Println(str3)
    }
  2. 格式化输出

package main

import "fmt"

func main() {
   var str = "hello"
   var str2 = " world"
   // str3 := str+str2
   str3 := fmt.Sprintf("%s %s", str, str2) // 格式化输出
   fmt.Println(str3)
}
  1. 求字符串长度

    package main
    
    import "fmt"
    
    func main() {
       var str = "hello"
       var str2 = " world"
       // str3 := str+str2
       str3 := fmt.Sprintf("%s %s", str, str2) // 格式化输出
       n := len(str3)
       fmt.Printf("len(str)=%d
    ", n)
    }
  2. 字符串的切片

    package main
    
    import "fmt"
    
    func main() {
       var str = "hello"
       var str2 = " world"
       // str3 := str+str2
       str3 := fmt.Sprintf("%s %s", str, str2) // 格式化输出
       substr := str3[0:5] // 和Python操作一致
       fmt.Println(substr)
    }
  3. 字符串反转

    package main
    
    import "fmt"
    
    func reverse(str string) string {
       var result []byte
       tmp := []byte(str) // 强制转换字符数组
       length := len(str)
       for i := 0; i < length; i++ {
          result = append(result, tmp[length-i-1])
       }
       return string(result)
    }
    func main() {
       var str = "hello"
       var str2 = " world"
       str3 := str + str2
       result := reverse(str3)
       fmt.Println(result)
    }

以上是关于学习golang的历程——持续更新的主要内容,如果未能解决你的问题,请参考以下文章

回归 | js实用代码片段的封装与总结(持续更新中...)

小程序各种功能代码片段整理---持续更新

golang代码片段(摘抄)

公开课|一个小运维的《Golang 入门心路历程》

学习HEXO的历程

golang 小知识-持续更新中