当前位置:   article > 正文

Go Roadmap-Basics中文笔记

Go Roadmap-Basics中文笔记

Go Roadmap-Basics

地址:https://roadmap.sh/golang
简介:Github star No.6 学习路线 Go 中译版
在这里插入图片描述

Learn the Basics

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

example:

package main
import ("fmt")

func main() {
  fmt.Println("Hello World!")
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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关键字
 var name type = value//不加tpye也可以推断
  • 1
  1. 用:=标志
name := value
  • 1

tips:“:=”和auto类似,不分配值的时候不能用。
并且只能在函数内使用。var可以在函数外面。

变量的自动初始化:
string初始为“”
int初始为0
bool初始为false

Data Types

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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里插入图片描述

For Loop

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

三内容循环:

sum := 0
for i := 1; i < 5; i++ {
	sum += i
}
fmt.Println(sum) // 10 (1+2+3+4)
  • 1
  • 2
  • 3
  • 4
  • 5

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

while循环:

n := 1
for n < 5 {
	n *= 2
}
fmt.Println(n) // 8 (1*2*2*2)
  • 1
  • 2
  • 3
  • 4
  • 5

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

sum := 0
for {
	sum++ // repeated forever
}
fmt.Println(sum) // never reached
  • 1
  • 2
  • 3
  • 4
  • 5

For-each range循环:

strings := []string{"hello", "world"}
for i, s := range strings {
	fmt.Println(i, s)
}
  • 1
  • 2
  • 3
  • 4
0 hello
1 world
  • 1
  • 2

String iteration: runes or bytes:

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

Range

在For Loop中

Conditional Statements

if 
if / else 
switch case 
  • 1
  • 2
  • 3
x := true
	if x {
		fmt.Println(s)
	}
  • 1
  • 2
  • 3
  • 4
if x == 100 {
		fmt.Println("Japan")
	} else {
		fmt.Println("Canada")
	}
  • 1
  • 2
  • 3
  • 4
  • 5
if x == 50 {
		fmt.Println("Germany")
	} else if x == 100 {
		fmt.Println("Japan")
	} else {
		fmt.Println("Canada")
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Errors/Panic/Recover

go不靠stack traces,也不靠try/catch
而是靠函数的值返回,和其他数据类型一样。

Conditional Statements

 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")
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Functions

问题引入:

定义和声明
返回名
多返回类型
不同的函数类型

函数是为解决特定问题的封装。
有个输入给个输出。

package main
import "fmt"

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

func main() {
	SimpleFunction()
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

带参数函数:

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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

带返回值函数:

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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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

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

传地址给函数:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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

Packages

包就是Go最强大的部分

fmt Package
math Package
string Package
  • 1
  • 2
  • 3

fmt:
在这里插入图片描述print就是输出完不换行,println就是输出完换行。
scanf和printf和C一样,还得指定%d

math:
在这里插入图片描述
sqrt是开根号
cbrt是开三次根

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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

strings:
在这里插入图片描述在这里插入代码片

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)

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
Output

golang strings
GOLANG STRINGS
I love Go Programming
  • 1
  • 2
  • 3
  • 4
  • 5

Type Casting

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

i := int(32.987) // 转化到int类型
  • 1

Go并不支持隐式类型转换(不同于C++)
并且从string转化为int时,可以用strconv包

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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Type Inference

尽管时静态类型,却不需要全都初始化定义的变量,
可以自动推断,通过右边的值。

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Arrays

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

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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
Hello World
[Hello World]
[2 3 5 7 11 13]
  • 1
  • 2
  • 3

Slices

类似于arrays,但是更强大,更灵活。
也是存储多个类型相同的值。
但是slice的长度可以生长和缩小。(形象)

语法:

myslice := []int{}
  • 1

上述这就是0长度,0容量的slice。
也可以初始化:

myslice := []int{1,2,3}
  • 1

怎么得到长度和容量呢?
用如下两个函数:len()和cap()

myslice2 := []string{"Go", "Slices", "Are", "Powerful"}
  fmt.Println(len(myslice2))
  fmt.Println(cap(myslice2))
  fmt.Println(myslice2)
  • 1
  • 2
  • 3
  • 4

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

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

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))
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
Result:

myslice = [12 13]
length = 2
capacity = 4
  • 1
  • 2
  • 3
  • 4
  • 5

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

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

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))
  • 1
  • 2
  • 3
  • 4

Maps

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

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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

想写一个空map,就是得用make()函数。
其他的var 或者:=会导致运行错误。

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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

Booleans
Numbers
Strings
Arrays
Pointers
Structs Interfaces (as long as the dynamic type supports equality)

获取map元素:

map_name[key]
  • 1

更新、添加map元素:
和创建是一样的。

删除map元素:

delete(map_name, key)
  • 1

查找特定元素:

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 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

maps are references(类似于return by references)
如果两个map都是同一个哈希表,那么修改一个,另一个也会变。

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

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, 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

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, 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

make

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

var intSlice = make([]int, 10)        // when length and capacity is same
var strSlice = make([]string, 10, 20) // when length and capacity is different
  • 1
  • 2
var employee = make(map[string]int)
    employee["Mark"] = 10
    employee["Sandy"] = 20
  • 1
  • 2
  • 3

make()函数创建channels:

channels是goroutines相互通信的中间件。
goroutines可以并发,相互之间要通信,共享资源。

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

structs

用户自定义类型,就是类似C++的struct
go语言没有继承,没有super

在这里插入图片描述上图是structs使用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/1003565
推荐阅读
相关标签
  

闽ICP备14008679号