Go语言基础
1.1 变量的定义
package main
import "fmt"
var (
aa = 2
ss = "kkk"
bb = true
)
func variableZeroValue() {
var a int
var s string
fmt.Println("%d %q\n", a, s)
}
func variableInitialValue() {
var a, b int = 3, 4
var s string = "abc"
fmt.Println(a, b, s)
}
func variableTypeDeduction() {
var a, b, c, s = 3, 4, true, "def"
fmt.Println(a, b, c, s)
}
func variableShorter() {
a, b, c, s := 3, 4, true, "def"
b = 5
fmt.Println(a, b, c, s)
}
func main() {
fmt.Println("hello world")
variableZeroValue()
variableInitialValue()
variableTypeDeduction()
variableShorter()
fmt.Println(aa, ss, bb)
}
1.1.1 使用var关键字
var a,b,c bool
var s1,s2 string = "hello", "world"
可放在函数内,或直接放在包内
可以使用var()集中定义变量
1.1.2让编译器自动决定类型
var a,b,i,s1,s2 = true, false,3,“hello”, “world”
1.1.3使用:=定义变量
a,b,i,s1,s2 := true, false,3,“hello”, “world”
只能在函数内使用
1.2 内建变量类型
complex定义复数
1.3 常量的定义
1.4 条件语句
package main
import (
"fmt"
"io/ioutil"
)
func main() {
const filename = "abc.txt"
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
}
switch会自动break,除非使用fallthrough
switch后面可以没有表达式
package main
import (
"fmt"
"io/ioutil"
)
func grade(score int) string {
g := ""
switch {
case score < 0 || score > 100:
panic(fmt.Sprintf("wrong score: %d", score))
case score < 60:
g = "F"
case score < 80:
g = "C"
case score < 90:
g = "B"
case score <= 100:
g = "A"
}
return g
}
func main() {
const filename = "abc.txt"
if contents, err := ioutil.ReadFile(filename); err != nil {
fmt.Println(err)
} else {
fmt.Printf("%s\n", contents)
}
fmt.Println(
grade(0),
grade(59),
grade(60),
grade(70),
grade(82),
grade(99),
grade(100),
//grade(101),
)
}
1.5 循环
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func convertToBin(n int) string {
result := ""
for ; n > 0; n /= 2 {
lsb := n % 2
result = strconv.Itoa(lsb) + result
}
return result
}
func printFile(filename string) {
file, err := os.Open(filename)
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
//死循环
func forever() {
for {
fmt.Println("abc")
}
}
func main() {
fmt.Println(
convertToBin(5), // 101
convertToBin(13), // 1101
convertToBin(72387885),
convertToBin(0),
)
printFile("abc.txt")
}
1.6 函数func
func eval(a, b int , op string) int {
}
package main
import "fmt"
func eval(a, b int, op string) int {
switch op {
case "+":
return a + b
case "-":
return a - b
case "*":
return a * b
case "/":
return a / b
default:
panic("unsupported operation: " + op)
}
}
func div(a, b int) (q, r int) {
q = a / b
r = a % b
return
}
func main() {
fmt.Println(eval(3, 4, "*"))
q, r := div(13, 3)
fmt.Println(q, r)
}
1.7 指针
var a int = 2
var pa *int = &a
*pa = 3
fmt.Println(a)
指针不能运算
1.7.1 值传递 引用传递
值传递做拷贝动作
引用传递做指向动作
go语言中对象的传递
go语言只有值传递这一种方式
func swap(a, b int) (int, int) {
return b, a
}
func main() {
fmt.Println(eval(3, 4, "*"))
q, r := div(13, 3)
fmt.Println(q, r)
a, b := 3, 4
a, b = swap(a, b)
fmt.Println(a, b)
}
1.8 数组,切片和容器
//数组
var arr1 [5]int
arr2 := [3]int{1, 3, 5}
arr3 := [...]int{2, 4, 6, 8, 10}
var grid [4][5]int
fmt.Println(arr1, arr2, arr3)
fmt.Println(grid)
数量写在类型的前面
package main
import "fmt"
func main() {
//数组
var arr1 [5]int
arr2 := [3]int{1, 3, 5}
arr3 := [...]int{2, 4, 6, 8, 10}
var grid [4][5]int
fmt.Println(arr1, arr2, arr3)
fmt.Println(grid)
for i := 0; i < len(arr3); i++ {
fmt.Println(arr3[i])
}
for _, v := range arr3 {
fmt.Println(v)
}
}
为什么要用range
① 意义明确,美观
② c++,没有类似的能力
③ java/python : 只能for each value,不能同时获取i, v
package main
import "fmt"
func printArray(arr *[5]int) {
arr[0] = 100
for i, v := range arr {
fmt.Println(i, v)
}
}
func main() {
//数组
var arr1 [5]int
arr2 := [3]int{1, 3, 5}
arr3 := [...]int{2, 4, 6, 8, 10}
var grid [4][5]int
fmt.Println(arr1, arr2, arr3)
fmt.Println(grid)
for i := 0; i < len(arr3); i++ {
fmt.Println(arr3[i])
}
for _, v := range arr3 {
fmt.Println(v)
}
fmt.Println("printArray(arr1)")
printArray(&arr1)
fmt.Println("printArray(arr3)")
printArray(&arr3)
//printArray(arr2) 报错是因为[3]int 和 [5]int在go语言中是不同的数据类型
fmt.Println("arr1 and arr3")
fmt.Println(arr1, arr3)
}
1.9 切片
package main
import "fmt"
func updateSlice(s []int) {
s[0] = 100
}
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("arr[2:6] = ", arr[2:6])
fmt.Println("arr[:6] = ", arr[:6])
s1 := arr[2:]
fmt.Println("arr[2:] =", s1)
s2 := arr[:]
fmt.Println("arr[:] =", s2)
fmt.Println("After updateSlice(s1)")
updateSlice(s1)
fmt.Println(s1)
fmt.Println(arr)
}
s3 := append(s2, 10)
s4 := append(s3, 11)
fmt.Println("s3, s4 = ", s3, s4)
fmt.Println("arr = ", arr)
切片的操作
1.10 Map
package main
import "fmt"
func main() {
m := map[string]string{ // map是一个hashmap
"name": "ccmouse",
"course": "golang",
"site": "imooc",
"quality": "notbad",
}
m2 := make(map[string]int) // m2 == empty map
var m3 map[string]int //m3 == nil
fmt.Println(m, m2, m3)
fmt.Println("Traversing map")
for k, v := range m {
fmt.Println(k, v)
}
fmt.Println("Getting values")
courseName := m["course"]
fmt.Println(courseName)
}
1.11 map例题 寻找最长不含有重复字符的子串
package main
import "fmt"
func lengthofNonRepeatingSubStr(s string) int {
lastOccurred := make(map[byte]int)
start := 0
maxLength := 0
for i, ch := range []byte(s) {
if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
start = lastI + 1
}
if i-start+1 > maxLength {
maxLength = i - start + 1
}
lastOccurred[ch] = i
}
return maxLength
}
func main() {
fmt.Println(
lengthofNonRepeatingSubStr("abcabcbb"))
fmt.Println(
lengthofNonRepeatingSubStr("bbbbbb"))
fmt.Println(
lengthofNonRepeatingSubStr("pwwkew"))
fmt.Println(
lengthofNonRepeatingSubStr(""))
fmt.Println(
lengthofNonRepeatingSubStr("b"))
fmt.Println(
lengthofNonRepeatingSubStr("abcdefg"))
}
1.12 面向对象和结构体
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func main() {
var root treeNode
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
nodes := []treeNode{
{value: 3},
{},
{6, nil, &root},
}
fmt.Println(nodes)
}
// 输出结果
//[{3 <nil> <nil>} {0 <nil> <nil>} {6 <nil> 0xc000004078}]
结构创建在堆上还是在栈上?
不需要知道
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func (node treeNode) print() {
fmt.Print(node.value, " ")
}
func (node *treeNode) setValue(value int) {
node.value = value
}
func createNode(value int) *treeNode {
return &treeNode{value: value}
}
func main() {
var root treeNode
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
root.left.right = createNode(2)
root.right.left.setValue(4)
root.right.left.print()
fmt.Println()
root.print()
root.setValue(100)
pRoot := &root
pRoot.print()
pRoot.setValue(200)
pRoot.print()
}
//输出值为:
//4
//3 100 200
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func (node treeNode) print() {
fmt.Print(node.value, " ")
}
func (node *treeNode) setValue(value int) {
if node == nil {
fmt.Println("setting value to nil node. Ignored.")
return
}
node.value = value
}
func (node *treeNode) traverse() {
if node == nil {
return
}
node.left.traverse()
node.print()
node.right.traverse()
}
func createNode(value int) *treeNode {
return &treeNode{value: value}
}
func main() {
var root treeNode
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
root.left.right = createNode(2)
root.right.left.setValue(4)
root.traverse()
}
//输出 0 2 3 4 5
1.13 封装
1.14 扩展已有类型
package main
import (
"awesomeProject/src/demo/golearning/tree"
"fmt"
)
type myTreeNode struct {
node *tree.Node
}
func (myNode *myTreeNode) postOrder() {
if myNode == nil || myNode.node == nil {
return
}
left := myTreeNode{myNode.node.Left}
right := myTreeNode{myNode.node.Right}
left.postOrder()
right.postOrder()
myNode.node.Print()
}
func main() {
var root tree.Node
root = tree.Node{Value: 3}
root.Left = &tree.Node{}
root.Right = &tree.Node{5, nil, nil}
root.Right.Left = new(tree.Node)
root.Left.Right = tree.CreateNode(2)
root.Right.Left.SetValue(4)
root.Traverse()
fmt.Println()
myRoot := myTreeNode{&root}
myRoot.postOrder()
fmt.Println()
}
//输出2 0 4 5 3
1.15使用内嵌类来扩展已有类型
1.16 go语言的依赖管理
1.17 go mod
1.18 最后目录的整理
把含有main函数的go文件分到几个不同的目录里面