Go Roadmap-Basics中文笔记

Go Roadmap-Basics

地址:https://roadmap.sh/golang

简介:Github star No.6 学习路线 Go 中译版

Learn the Basics

Go特点:静态类型,运行速度快,编译语言,编译速度快,自动垃圾回收,没有类和对象,没有继承关系。

example:

go 复制代码
package main
import ("fmt")

func main() {
  fmt.Println("Hello World!")
}

Basic Syntax

基本语法:包申明、导包、函数、语句。

上面的代码块讲解:

  1. 属于main包
  2. 导入了fmt这个包
  3. 空行更可读
  4. func main(){}是函数
  5. fmt.Println()是fmt包里的函数,可以打印文字。

基本语句:fmt.Println("Hello World!")

敲击enter键就可以结束一行(不用;)

所以:"{"不可以在一行的开头

Variables in Go

最常用变量类型:int float32 string bool

创建变量:

  1. 用var关键字
go 复制代码
 var name type = value//不加tpye也可以推断
  1. 用:=标志
go 复制代码
name := value

tips:":="和auto类似,不分配值的时候不能用。

并且只能在函数内使用。var可以在函数外面。

变量的自动初始化:

string初始为""

int初始为0

bool初始为false

Data Types

go 复制代码
package main
import ("fmt")

func main() {
  var a bool = true     // Boolean
  var b int = 5         // Integer
  var c float32 = 3.14  // Floating point number
  var d string = "Hi!"  // String

  fmt.Println("Boolean: ", a)
  fmt.Println("Integer: ", b)
  fmt.Println("Float:   ", c)
  fmt.Println("String:  ", d)
}

For Loop

go只有一种循环体,就是for循环。

三内容循环:

go 复制代码
sum := 0
for i := 1; i < 5; i++ {
	sum += i
}
fmt.Println(sum) // 10 (1+2+3+4)

区别在于:没有() 没有int 用的是:=。

while循环:

go 复制代码
n := 1
for n < 5 {
	n *= 2
}
fmt.Println(n) // 8 (1*2*2*2)

无限循环:(没有终止条件)

go 复制代码
sum := 0
for {
	sum++ // repeated forever
}
fmt.Println(sum) // never reached

For-each range循环:

go 复制代码
strings := []string{"hello", "world"}
for i, s := range strings {
	fmt.Println(i, s)
}
go 复制代码
0 hello
1 world

String iteration: runes or bytes:

go 复制代码
for i, ch := range "日本語" {
	fmt.Printf("%#U starts at byte position %d\n", ch, i)
}
go 复制代码
U+65E5 '日' starts at byte position 0
U+672C '本' starts at byte position 3
U+8A9E '語' starts at byte position 6

Range

在For Loop中

Conditional Statements

if 
if / else 
switch case 
go 复制代码
x := true
	if x {
		fmt.Println(s)
	}
go 复制代码
if x == 100 {
		fmt.Println("Japan")
	} else {
		fmt.Println("Canada")
	}
go 复制代码
if x == 50 {
		fmt.Println("Germany")
	} else if x == 100 {
		fmt.Println("Japan")
	} else {
		fmt.Println("Canada")
	}

Errors/Panic/Recover

go不靠stack traces,也不靠try/catch

而是靠函数的值返回,和其他数据类型一样。

Conditional Statements

go 复制代码
 if num := 9; num < 0 {
        fmt.Println(num, "is negative")
    } else if num < 10 {
        fmt.Println(num, "has 1 digit")
    } else {
        fmt.Println(num, "has multiple digits")
    }

Functions

问题引入:

定义和声明

返回名

多返回类型

不同的函数类型

函数是为解决特定问题的封装。

有个输入给个输出。

go 复制代码
package main
import "fmt"

func SimpleFunction() {
	fmt.Println("Hello World")
}

func main() {
	SimpleFunction()
}

带参数函数:

go 复制代码
package main
import "fmt"

func add(x int, y int) {
	total := 0
	total = x + y
	fmt.Println(total)
}

func main() {
	// Passing arguments
	add(20, 30)
}

带返回值函数:

go 复制代码
package main
import "fmt"

func add(x int, y int) int {
	total := 0
	total = x + y
	return total
}

func main() {
	// Accepting return value in varaible
	sum := add(20, 30)
	fmt.Println(sum)
}

return返回值可以不写特定变量。

return返回值可以是多值,直接写return就可以。

传地址给函数:

go 复制代码
package main
import "fmt"

func update(a *int, t *string) {
	*a = *a + 5      // defrencing pointer address
	*t = *t + " Doe" // defrencing pointer address
	return
}

func main() {
	var age = 20
	var text = "John"
	fmt.Println("Before:", text, age)
	update(&age, &text)
	fmt.Println("After :", text, age)
}

Output
Before: John 20
After : John Doe 25

匿名函数:

匿名函数就是没有函数名的函数。

Packages

包就是Go最强大的部分

fmt Package
math Package
string Package

fmt:
print就是输出完不换行,println就是输出完换行。

scanf和printf和C一样,还得指定%d

math:

sqrt是开根号

cbrt是开三次根

go 复制代码
func main() {
  // find the square root
  fmt.Println(math.Sqrt(25))    // 5
  // find the cube root
  fmt.Println(math.Cbrt(27))    // 3
  // find the maximum number
  fmt.Println(math.Max(21, 18))    // 21
  // find the minimum number
  fmt.Println(math.Min(21, 18))    // 18
  // find the remainder
  fmt.Println(math.Mod(5, 2))    // 1
}

strings:
在这里插入代码片

go 复制代码
package main
import (
  "fmt"
  "strings"
  )
func main() {
  lower := strings.ToLower("GOLANG STRINGS")
  fmt.Println(lower)
  
  upper := strings.ToUpper("golang strings")
  fmt.Println(upper)

  stringArray := []string{"I love", "Go Programming"}
  joinedString := strings.Join(stringArray, " ");
  fmt.Println(joinedString)

}
go 复制代码
Output

golang strings
GOLANG STRINGS
I love Go Programming

Type Casting

转化一个类型到另一个类型

go 复制代码
i := int(32.987) // 转化到int类型

Go并不支持隐式类型转换(不同于C++)

并且从string转化为int时,可以用strconv包

go 复制代码
package main
import (
    "fmt"
    "strconv"
)
func main() {
    var s string = "42"
    v, _ := strconv.Atoi(s)       // convert string to int
    fmt.Println(v)    // 42
     
    var i int = 42
    str := strconv.Itoa(i)        // convert int to string
    fmt.Println(str) // 42
}

Type Inference

尽管时静态类型,却不需要全都初始化定义的变量,

可以自动推断,通过右边的值。

go 复制代码
package main
import "fmt"
func main() {
	// Multiple variable declarations with inferred types
    var firstName, lastName, age, salary = "John", "Maxwell", 28, 50000.0

    fmt.Printf("firstName: %T, lastName: %T, age: %T, salary: %T\n", 
        firstName, lastName, age, salary)
}

# Output
firstName: string, lastName: string, age: int, salary: float64

如果在函数体内,最好还用;=

go 复制代码
package main
import "fmt"
func main() {
	name := "Rajeev Singh"
	age, salary, isProgrammer := 35, 50000.0, true
	fmt.Println(name, age, salary, isProgrammer)
}

# Output
Rajeev Singh 35 50000 true

Arrays

就是一组相同元素的集合。

go 复制代码
package main
import "fmt"

func main() {
	var a [2]string
	a[0] = "Hello"
	a[1] = "World"
	fmt.Println(a[0], a[1])
	fmt.Println(a)

	primes := [6]int{2, 3, 5, 7, 11, 13}
	fmt.Println(primes)
}
go 复制代码
Hello World
[Hello World]
[2 3 5 7 11 13]

Slices

类似于arrays,但是更强大,更灵活。

也是存储多个类型相同的值。

但是slice的长度可以生长和缩小。(形象)

语法:

go 复制代码
myslice := []int{}

上述这就是0长度,0容量的slice。

也可以初始化:

go 复制代码
myslice := []int{1,2,3}

怎么得到长度和容量呢?

用如下两个函数:len()和cap()

go 复制代码
myslice2 := []string{"Go", "Slices", "Are", "Powerful"}
  fmt.Println(len(myslice2))
  fmt.Println(cap(myslice2))
  fmt.Println(myslice2)

上述的len就是4,而cap也是4。

怎么从一个数组创建slice呢?

go 复制代码
package main
import ("fmt")

func main() {
  arr1 := [6]int{10, 11, 12, 13, 14,15}
  myslice := arr1[2:4]

  fmt.Printf("myslice = %v\n", myslice)
  fmt.Printf("length = %d\n", len(myslice))
  fmt.Printf("capacity = %d\n", cap(myslice))
}
go 复制代码
Result:

myslice = [12 13]
length = 2
capacity = 4

解释:【2:4】指的是左闭右开区间的,所以就是要索引为2和3的数组中的数字,所以长度是2,但是因为切隔切了从2开始后面所有的,所以容量是4。

也可以用make()函数来创建slice:

go 复制代码
myslice1 := make([]int, 5, 10)
  fmt.Printf("myslice1 = %v\n", myslice1)
  fmt.Printf("length = %d\n", len(myslice1))
  fmt.Printf("capacity = %d\n", cap(myslice1))

Maps

maps是用于存放键值对组合的,无序。

map的默认值是nil。

go 复制代码
package main
import ("fmt")

func main() {
  var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"}
  b := map[string]int{"Oslo": 1, "Bergen": 2, "Trondheim": 3, "Stavanger": 4}

  fmt.Printf("a\t%v\n", a)
  fmt.Printf("b\t%v\n", b)
}

Result:

a   map[brand:Ford model:Mustang year:1964]
b   map[Bergen:2 Oslo:1 Stavanger:4 Trondheim:3]

也可以用make()函数创建map

go 复制代码
package main
import ("fmt")

func main() {
  var a = make(map[string]string) // The map is empty now
  a["brand"] = "Ford"
  a["model"] = "Mustang"
  a["year"] = "1964"
                                 // a is no longer empty
  b := make(map[string]int)
  b["Oslo"] = 1
  b["Bergen"] = 2
  b["Trondheim"] = 3
  b["Stavanger"] = 4

  fmt.Printf("a\t%v\n", a)
  fmt.Printf("b\t%v\n", b)
}

想写一个空map,就是得用make()函数。

其他的var 或者:=会导致运行错误。

go 复制代码
package main
import ("fmt")

func main() {
  var a = make(map[string]string)
  var b map[string]string 

  fmt.Println(a == nil)
  fmt.Println(b == nil)
}

Result:

false
true

map可以用什么类型的数据做键呢?

Booleans

Numbers

Strings

Arrays

Pointers

Structs Interfaces (as long as the dynamic type supports equality)

获取map元素:

go 复制代码
map_name[key]

更新、添加map元素:

和创建是一样的。

删除map元素:

go 复制代码
delete(map_name, key)

查找特定元素:

go 复制代码
package main
import ("fmt")

func main() {
  var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964", "day":""}

  val1, ok1 := a["brand"] // Checking for existing key and its value
  val2, ok2 := a["color"] // Checking for non-existing key and its value
  val3, ok3 := a["day"]   // Checking for existing key and its value
  _, ok4 := a["model"]    // Only checking for existing key and not its value

  fmt.Println(val1, ok1)
  fmt.Println(val2, ok2)
  fmt.Println(val3, ok3)
  fmt.Println(ok4)
}
Result:

Ford true 
 false 
 true 
true 

maps are references(类似于return by references)

如果两个map都是同一个哈希表,那么修改一个,另一个也会变。

迭代输出maps元素:

range来迭代输出,但是是无序的。因为maos本身是无序的数据结构。

go 复制代码
package main
import ("fmt")

func main() {
  a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}

  for k, v := range a {
    fmt.Printf("%v : %v, ", k, v)
  }
}

Result:
two : 2, three : 3, four : 4, one : 1, 

如果想要有序,也可以的,使用如下的方式:

go 复制代码
package main
import ("fmt")

func main() {
  a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}

  var b []string             // defining the order
  b = append(b, "one", "two", "three", "four")

  for k, v := range a {        // loop with no order
    fmt.Printf("%v : %v, ", k, v)
  }

  fmt.Println()

  for _, element := range b {  // loop with the defined order
    fmt.Printf("%v : %v, ", element, a[element])
  }
}

Result:
two : 2, three : 3, four : 4, one : 1, 
one : 1, two : 2, three : 3, four : 4, 

make

make()函数可以创建、初始化slices,

maps、channels。

go 复制代码
var intSlice = make([]int, 10)        // when length and capacity is same
var strSlice = make([]string, 10, 20) // when length and capacity is different
go 复制代码
var employee = make(map[string]int)
    employee["Mark"] = 10
    employee["Sandy"] = 20

make()函数创建channels:

channels是goroutines相互通信的中间件。

goroutines可以并发,相互之间要通信,共享资源。

go 复制代码
package main
import "fmt"

func main() {
  
  // create channel of integer type
   number := make(chan int)
 
  // access type and value of channel
  fmt.Printf("Channel Type: %T\n", number)
  fmt.Printf("Channel Value: %v", number)

}

Output
Channel Type: chan int
Channel Value: 0xc00007a060

structs

用户自定义类型,就是类似C++的struct

go语言没有继承,没有super

上图是structs使用。

相关推荐
高山我梦口香糖30 分钟前
[react]searchParams转普通对象
开发语言·前端·javascript
冷眼看人间恩怨43 分钟前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
信号处理学渣1 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客1 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
jasmine s1 小时前
Pandas
开发语言·python
biomooc1 小时前
R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
开发语言·r语言
骇客野人1 小时前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
black^sugar1 小时前
纯前端实现更新检测
开发语言·前端·javascript
404NooFound2 小时前
Python轻量级NoSQL数据库TinyDB
开发语言·python·nosql
用余生去守护2 小时前
python报错系列(16)--pyinstaller ????????
开发语言·python