Thanks to visit codestin.com
Credit goes to github.com

Skip to content

tsqqqqqq/Go-learn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go-learn

根据慕课网重新初学Go语言Google资深工程师深度讲解go语言,由浅入深掌握 此仓库记录Go基础、进阶等学习代码

安装部署

  1. 登录go官方网站 GoLang 根据操作系统安装下载对应的安装包

  2. 安装golang

  3. 打开命令行 输入 go verison 出现如下内容代表安装成功

    img.png

  4. 配置国内代理GOPROXY: go env -w GOPROXY=http://goproxy.cn

  5. 配置GO111MODEL: go env -w GO111MODEL=on

学习路线

个人暂时整理的学习路线 会不断更新内容 img_1.png

基础篇

语法篇

  1. 变量(var)
  2. GO语言的内建变量类型
  3. 常量与枚举(const)
  4. 程序结构控制(switch、if)
  5. 循环(for)
  6. 函数(func)
  7. 指针(pointer)

变量(var)

var 变量名 变量类型 例: var name string

在Go中变量使用关键字 var 进行修饰 。与Java不同的是变量类型放置在最后,变量名放置在中间。 在Go中的变量在定义时,若未同时对变量进行赋初值,会给变量提供一个初值,若变量类型是int型则初值为0. 若变量类型是string则初值为""

package main

import "fmt"

func main() {
   var age int
   var name string
   fmt.Println(age,name)
}

0

为变量赋初值的方法是在声明变量时即可对变量赋初值

package main

import "fmt"

func main() {
   var age int
   var name string
   //赋值的第一种方法
    age = 18
    name = "tsqqqqq"
    //定义变量时 不定义数据类型 go语言的类型推断会自动帮我们判断当前变量的类型
    var check = true
   fmt.Println(age, name,check)
}

18 tsqqqqqq true

上述我们看到两种对类型赋初值的方法,第一种为先声明变量,再将变量赋初值。第二种为借由GoLang中的类型推断来对推断变量的类型从而把值赋给变量。

来让我们康康go语言中对变量的声明和赋初值的简易操作。

package main

import "fmt"

func main() {
   age,name,check :=18,"tsqqqqqq",true
   fmt.Println(age, name,check)
}

18 tsqqqqqq true

上述例子也同样展现了go语言中的一个特性。支持多变量同时赋值。牛吧!!!不过特殊的 这样的语法糖仅可以在函数内使用

在go语言中 没有全局变量,最大的作用域是局限于同一个包范围下单的变量。只需要在包内对变量进行声明,所有同一个package下的go文件都可以使用该变量 也可以认为是一个近似于全局变量的对象。

如果我们需要一次性定义很多变量,而我们又不想写太多的代码的话,可以使用var()集中定义变量的形式来对变量进行定义。

package main

import "fmt"
var(
	age = 18
	name = "tsqqqqqq"
	check = true
)
func main() {
   fmt.Println(age, name,check)
}

18 tsqqqqqq true

Go语言基础的内建类型

bool string

(u)int (u)int8 (u)int16 (u)int32 (u)int64 uintptr

byte rune

float32 flot64 complex64 complex128

在Go语言中包含了以上列举的内建数据类型 其中 int类型由1字节-64字节 其中int8代表的就是一个byte,在而uint代表无符号整型。 uintptr 代表整型类型的指针。其中整型的取值范围分别如下图表示 img_2.png

bool 与 string 还有 byte 都是我们的老homie了 ,bool仅包含两个值 true or false,string代表字符串类型。byte代表字节类型 float32 与 float64 分别等价于c语言中的double与float 是我们认识的浮点类型。

complex64 其实是由两个float32组成的,代表32位计算机的复数类型 同理 complex128 是由两个float64组成的,代表64位计算机的复数类型

哦豁 有新朋友 rune 其实就是字符类型 代表单个Unicode字符 在go语言中的定义它 rune int32 用来处理utf-8的unicode字符

重点为,go语言中不存在隐式的类型转换,若需要对类型进行转换必须使用强制类型转换

类型(需要转换的类型) int(float)

常量与枚举

const 常量名 常量类型 例 const pi float64

有变量就自然有常量,在go语言中,常量的定义和使用与变量基本无差。只需要注意的是,定义了常量之后我们无法再去对这个常量的值进行改变。 默认为java中被final修饰过的值.

在go语言中将枚举分为两种枚举

  1. 自定义枚举:指的是在const()集中定义的常量块内进行自定义的操作
  2. 自增枚举:在定义枚举的时候使用iota关键字,可以对修饰的常量赋值为1 而他之后的枚举类型会自增1
package main
/**
自定义枚举类型
*/
const (
	cpp    = "cpp"
	java   = "java"
	python = "python"
)
/**
自增枚举
 */
const (
   b = 1 << (10 * iota)
   kb
   mb
   gb
   tb
   pb
)

程序结构控制(switch,if)

switch { ...case :} or switch check {...case}

直接上代码举例说明

package main

import "fmt"

const (
   add = "+"
   sub = "-"
   mul = "*"
   div = "/"
)

func operation(op string, a, b int) (res int) {
   switch op {
   case add:
      res = a + b
   case sub:
      res = a - b
   case mul:
      res = a * b
   case div:
      res = a / b
   default:
      panic("不存在该操作符")
   }
   return
}
func main() {
   res := operation(add, 3, 4)
   fmt.Println(res)
}

Go语言中的switch条件判断可以在switch关键字后使用也可以在case中进行判断。在Go语言中 case无需使用break来退出,除非使用fallthrough。

if check {}

if 的语法也非常简单,它无需判断条件外部添加括号,毕竟go语言一切以简单为主。 上代码!

package main

import (
   "fmt"
   "io/ioutil"
)

func main() {
   const filename = "abc.txt"
   contexts, err := ioutil.ReadFile(filename)
   if err != nil {
      panic(err)
   }
   fmt.Printf("%s\n", contexts)
}

特殊的是 go语言中的if语句条件判断时可以赋值,而那个在if语句条件判断时赋值的变量,作用域仅在该if代码块中。其他代码块无法引用该变量。

package main

import "fmt"

func main() {
   if i := 17; i >= 18 {
      fmt.Println("成年人")
   }else{
   	  fmt.Println("未成年,年龄为:",i)
   }
}

循环(for)

在go语言中,没有while循环,因为go语言的设计是为了简便,而for关键字的操作完全可以把while、do-while替换掉 让我们分别来看看三种for循环的范例:

package main

import (
   "fmt"
   "strconv"
)

func f1(str string) {
   for v:=range str{
   	    fmt.Println(v)
   }
}
func f2(N int) {
   for N > 0 {
      fmt.Println(2 * N)
      N -= 1
   }
}
func f3(N int) string {
   res := ""
   for ; N > 0; N /= 2 {
      N %= 2
      res = strconv.Itoa(N) + res
   }
   return res
}
func main() {
   f1("tsqqqqqq")
   f2(10)
   fmt.Println(f3(256))
}

以上是常见的三种for循环的使用方式:

  1. f1中的循环使用了一个关键字 range,是Go语言提供的,类似与foreach的循环方式,可以对数组,字符串(字符串底层是[]byte),slice(切片),map进行遍历
  2. f2中的循环我们可以看到,他就是while麻,只不过使用了for关键字而已。这下我们知道了go语言中对简单开发的理解是多么的深刻
  3. f3中也是我们常见的循环结构,值,循环次数和离开条件,循环规则。

函数(func)

func 函数名(...参数) 返回值{}

go语言支持多返回值 即有语法为 func 函数名(...参数) 返回值1,返回值2{}

go语言是函数式编程,与其他语言不同的地方在于 func函数也可以作为参数传入一个新的函数作为使用

上述代码中已经存在许多函数了,这里我们就特别针对第三点来做一个代码的描述

package main

import (
	"fmt"
	"reflect"
	"runtime"
)

const (
	add = "+"
	sub = "-"
	mul = "*"
	div = "/"
)

func operation(op string, a, b int) (int, error) {
	res := 0
	var err error
	switch op {
	case add:
		res, err = a+b, nil
	case sub:
		res, err = a-b, nil
	case mul:
		res, err = a*b, nil
	case div:
		res, err = a/b, nil
	default:
		fmt.Errorf("当前操作错误 导致错误的操作为 %s", operation)
	}
	return res, err
}

func call(operation func(op string, a, b int) (int, error), op string, a, b int) (int, error) {
	funcPtr := reflect.ValueOf(operation).Pointer()
	funcName := runtime.FuncForPC(funcPtr).Name()
	fmt.Printf("当前执行的函数名为 %s\n", funcName)
	return operation(op, a, b)
}

func main() {
	res, err := call(operation, add, 3, 4)
	if err != nil {
		panic(err)
	}
	fmt.Println(res)
}

指针

unsafe.pointer

容器篇

  1. 数组
  2. Slice 切片
  3. map

“面向对象”

依赖管理

面向接口

函数式编程

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages