zoukankan      html  css  js  c++  java
  • 16.go语言基础学习(上)——2019年12月16日

    2019年12月13日10:35:20

    1.介绍

    2019年10月31日15:09:03

    image-20191031150916257 image-20191031150951050 image-20191031151030511 image-20191031151138476 image-20191031151155689 image-20191031151211549 image-20191031152835829

    2.基本语法

    2.1 定义变量

    2019年10月31日16:12:34

    1.函数外必须使用var定义变量

    image-20191031161310008
    var a=1
    b:=5
    

    声明变量的一般形式是使用 var 关键字:

    var name type
    

    其中,var 是声明变量的关键字,name 是变量名,type 是变量的类型。

    2.没有全局变量说法,只有包变量

    3.集中定义变量

    var (
    	a int
    	c string
    	d bool
    )
    

    4.使用var关键字

    var a,b,c bool
    
    var s1,s2 string="hello","world"
    

    5.使用:=定义变量

    只能在函数体内使用

    a,b,c:=1,2,"123"
    

    6.基本类型

    Go语言的基本类型有:
    bool
    string
    int、int8、int16、int32、int64
    uint、uint8、uint16、uint32、uint64、uintptr
    byte // uint8 的别名
    rune // int32 的别名 代表一个 Unicode 码
    float32、float64
    complex64、complex128
    

    7.源代码:

    package main
    
    import "fmt"
    
    var (
    	a int
    	c string
    	d bool
    )
    
    func main() {
    	varible()
    	varibleType()
    	varibleSimple()
    	fmt.Println(d)
    
    }
    
    func varible(){
    	var s int
    	var t string
    	fmt.Printf("%d %q
    ",s,t)
    
    }
    
    func varibleSimple(){
    	a,b,c :=1,2,"abc"
    	b=5
    	fmt.Println(a,b,c)
    }
    
    func varibleType(){
    
    	var a,b,c=1,2,"abc"
    	fmt.Println(a,b,c)
    
    }
    
    

    2.2 go内建变量类型

    2019年10月31日16:26:53

    1.复数类型

    两种复数类型,分别是 complex64(32 位实数和虚数)类型和 complex128(64 位实数和虚数)类型。

    内置的 complex 函数用于构建复数,内建的 real 和 imag 函数分别返回复数的实部和虚部:

    var x complex128 = complex(1, 2) // 1+2i
    var y complex128 = complex(3, 4) // 3+4i
    fmt.Println(x*y)                 // "(-5+10i)"
    fmt.Println(real(x*y))           // "-5"
    fmt.Println(imag(x*y))           // "10"
    

    复数使用 re+imi 来表示,其中 re 代表实数部分,im 代表虚数部分,i 代表根号负 1。如果一个浮点数或一个十进制整数后面跟着一个 i,例如 3.141592i 或 2i,它将构成一个复数的虚部,而复数的实部是 0

    fmt.Println(1i * 1i) // "(-1+0i)", i^2 = -1
    

    2.强制类型转换

    类型转换是强制的

    规定是什么类型的参数一定要必须是

    返回什么类型也得强转。

    3.正弦

    正弦函数由 math 包提供,函数入口为 math.Sin,正弦函数的参数为 float64,返回值也是 float64。在使用正弦函数时,根据实际精度可以进行转换。

    2.3 常量与枚举

    2019年10月31日18:08:39

    1.常量

    //常量
    const s,t=1,2
    const y int=5
    

    2.枚举

    iota 开始生成枚举值, 默认为0

    iota 不仅可以生成每次增加 1 的枚举值。还可以利用 iota 来做一些强大的枚举常量值生成器

    //枚举
    func enums()  {
    	const(
    		cpp=iota
    		java
    		python
    		golang
    	)
    	//b,kb,mb,gb,tb,pb
    	
    	const(
    		b=1<<(10*iota)
    		kb
    		mb
    		gb
    		tb
    		pb
    	)
    
    	fmt.Println(cpp,java,python,golang)
    	fmt.Println(b,kb,mb,gb,tb,pb)
    }
    
    

    3.总结

    1. 变量类型写在变量名之后
    2. 编译器可推测变量类型
    3. 没有char,只有rune
    4. 原生支持复数类型

    2.4 条件语句

    2019年10月31日18:24:56

    1.if的条件里不需要括号

    func varible1() int {
    	var a int=5
    	if a>3 {
    		return 100
    	}else{
    		return 122
    	}
    }
    

    2.if的条件里可以赋值

    	if contents,err:=ioutil.ReadFile(filename); err!=nil{
    			fmt.Println(err)
    		}else {
    		fmt.Println("%s
    ", contents)
    	}
    
    

    3.switch

    func eval(a,b int,op string) int{
    	var result int
    	switch op {
    	case "+":
    		result = a + b
    	case "-":
    		result = a - b
    	default:
    		panic("unsupported" + op)
    	}
    	return result
    }
    
    

    4.switch会自动break,除非使用fallthrough

    5.switch后可以没有表达式

    image-20191031190306641

    6.源码

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    )
    
    func main() {
    
    	const filename="abc.txt"
    
    	//contents,err:=ioutil.ReadFile(filename)
    	//if err!=nil{
    	//	fmt.Println(err)
    	//}else {
    	//	fmt.Println("%s
    ",contents)
    	//}
    	//
    	//fmt.Println(contents)
    	if contents,err:=ioutil.ReadFile(filename); err!=nil{
    			fmt.Println(err)
    		}else {
    		fmt.Println("%s
    ", contents)
    	}
    
    	fmt.Println(eval(3,1,"+"))
    	
    }
    
    func varible1() int {
    	var a int=5
    	if a>3 {
    		return 100
    	}else{
    		return 122
    	}
    }
    
    func eval(a,b int,op string) int{
    	var result int
    	switch op {
    	case "+":
    		result = a + b
    	case "-":
    		result = a - b
    	default:
    		panic("unsupported" + op)
    	}
    	return result
    }
    
    

    2.5 循环

    2019年10月31日19:12:25

    1.for的条件里不需要括号

    //整数转成二进制
    func main() {
    
    	fmt.Println(
    		convertToBin(5),
    		convertToBin(15),
    		)
    	
    }
    
    //循环
    func convertToBin(n int) string {
    	result:=""
    	for ;n>0;n/=2{
    		lsb:=n%2
    		result=strconv.Itoa(lsb)+result
    	}
    	return  result
    }
    

    2.没有while

    3.源码

    package main
    
    import (
    	"bufio"
    	"fmt"
    	"os"
    	"strconv"
    )
    
    func main() {
    
    	fmt.Println(
    		convertToBin(5),
    		convertToBin(15),
    		)
    	printFile("abc.txt")
    }
    
    //循环
    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)
    	}else{
    		scanner:=bufio.NewScanner(file)
    		for scanner.Scan(){
    			fmt.Println(scanner.Text())
    		}
    	}
    }
    

    2019年10月31日19:28:28

    2.6 函数

    2019年10月31日19:28:41

    1.函数可以返回多个值

    func div(a,b int)(q,r int){
    	return a/b,a%b
    }
    
    func main() {
    	fmt.Println(123)
    	div(13,4)
    
    }
    

    2.返回多个值可以起名字

    3.没有默认参数,可选参数

    4.介绍

    函数的基本组成为:关键字 func、函数名、参数列表、返回值、函数体和返回语句,每一个程序都包含很多的函数,函数是基本的代码块。

    因为Go语言是编译型语言,所以函数编写的顺序是无关紧要的,

    鉴于可读性的需求,最好把 main() 函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(例如函数被调用的顺序)。

    2.7 指针

    2019年10月31日20:19:48

    1.指针不能运算

    指针(pointer)在Go语言中可以被拆分为两个核心概念:

    • 类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
    • 切片,由指向起始元素的原始指针、元素数量和容量组成。

    切片比原始指针具备更强大的特性,而且更为安全。切片在发生越界时,运行时会报出宕机,并打出堆栈,而原始指针只会崩溃。

    2.go语言只有值传递

    image-20191031202634060 image-20191031202743997

    3.

    每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用在变量名前面添加&

    ptr := &v   // v 的类型为 T
    

    其中 v 代表被取地址的变量,变量 v 的地址使用变量 ptr 进行接收,ptr 的类型为*T

    称做 T 的指针类型,*代表指针。

    3.数组切片容器

    3.1 数组

    2019年10月31日20:37:02

    1.定义数组的集中方法

      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)
    

    image-20191031204120538

    2.遍历数组 range

    //传统方式
    for i:=0;i< len(arr3);i++{
    		fmt.Println(arr3[i])
    	}
    

    使用range

    for i:=range arr3{
    		fmt.Println(arr3[i])
    	}
    

    获得索引和值

    	for i,v:=range arr3{
    		fmt.Println(i,v)
    	}
    
    image-20191031204633138

    3.range遍历时索引不想用到

    	for _,v:=range arr3{
    		fmt.Println(v)
    	}
    

    4.为什么用到range

    image-20191031204944129

    5.数组是值类型

    6.[10]int 和[20]int是不同类型

    7.调用func f(arr [10]int)会 拷贝 数组

    8.go语言一般不直接使用数组

    3.2 切片-slice

    2019年10月31日20:55:34

    image-20191031205824845

    1.介绍

    切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型)

    这个片段可以是整个数组,也可以是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内。

    切片一般用于快速地操作一块数据集合,如果将数据集合比作切糕的话,切片就是你要的“那一块”,切的过程包含从哪里开始(切片的起始位置)及切多大(切片的大小),容量可以理解为装切片的口袋大小,如下图所示。

    img

    2.切片是对数组的视图,同步更新。

    //更新视图
    func updateArr(arr []int){
    	arr[0]=1000
    }
    
    func main() {
    	arr3:=[...]int{2,4,6,7,8,5,4,33}
    	s:=arr3[2:6]
    	fmt.Println(s)
    	fmt.Println("arr[:6]= ",arr3[:6])
    	fmt.Println("arr[2:]= ",arr3[2:])
    	fmt.Println("arr[:]= ",arr3[:])
    	s1:=arr3[2:]
    	s2:=arr3[:]
    	updateArr(s1)
    	fmt.Println("更新过的s1:=",s1)
    	fmt.Println("更新过的arr:=",arr3)
    	updateArr(s2)
    	fmt.Println("更新过的s2:=",s2)
    	fmt.Println("更新过的arr:=",arr3)
    
    }
    

    image-20191101120825792

    3.slice本身没有数据,是对底层array的一个view

    4.resilce,不断的切片

    5.slice扩展

    4.为什么用到range

    image-20191101121901340 image-20191101121919104
    	arr:=[...]int{1,2,3,4,5,6,7,8}
    	fmt.Println("arr:=",arr)
    	s1:=arr[2:6]
    	s2:=s1[3:5]
    	fmt.Printf("s1=%v,len(s1)=%d,cap(s1)=%d
    ",s1,len(s1),cap(s1))
    	fmt.Printf("s2=%v,len(s2)=%d,cap(s2)=%d
    ",s2,len(s2),cap(s2))
    

    image-20191101122907451

    6.slice实现

    image-20191101122158601

    7.slice可以向后扩展,不可以向前扩展

    8.s[i]不可以超越len(s),向后扩展不可以超越底层数组cap(s)

    9.向slice添加元素

    s4和s5不再是arr的视图了

    	s3:= append(s2, 10)
    	s4:=append(s3,11)
    	s5:=append(s4,12)
    	fmt.Println("s3,s4,s5",s3,s4,s5)
    	fmt.Println("arr:=",arr)
    

    image-20191101123729156

    10.添加元素时超越cap,系统会重新分配更大的底层数组

    11.由于值传递,必须接受append的返回值

    s=append(s,val)
    

    12.定义slice

    var s []int
    

    13.知道长度,初始化slice

    func printSilce(arr []int){
    	fmt.Printf("s=%v,len=%d,cap=%d
    ",arr,len(arr),cap(arr))
    }
    func main() {
    	s1:=[]int{2,4}
    	printSilce(s1)
    
    	s2:=make([]int,16)
    	s3:=make([]int,16,32)
    	
    	printSilce(s2)
    	printSilce(s3)
    
    }
    
    

    image-20191101125248148

    14.copy slice

    copy(s2,s1)
    

    15.slice删除某个元素

    	copy(s2,s1)
    
    	printSilce(s2)
    
    	s5:=append(s2[:3],s2[4:]...)
    	printSilce(s5)
    

    image-20191101125918617

    16.删除头尾

    	//删除头尾
    	front:=s5[0]
    	s5=s5[1:]
    
    	tail:=s5[len(s5)-1]
    	s5=s5[:len(s5)-1]
    
    	fmt.Println(front,tail)
    
    	printSilce(s5)
    

    image-20191101130236425

    2019年11月01日13:03:18

    3.3 map

    2019年11月01日13:03:26

    1.介绍

    Go语言中 map 是一种特殊的数据结构,一种元素对(pair)的无序集合,pair 对应一个 key(索引)和一个 value(值),所以这个结构也称为关联数组或字典,这是一种能够快速寻找值的理想结构,给定 key,就可以迅速找到对应的 value。

    2.map建立方式

    	m:=map[string] string{
    		"name":"jixi",
    		"age":"13",
    	}
    
    	m3:=make(map[string]int)
    
    	fmt.Println(m,m3)
    

    image-20191101130959805

    3.遍历map

    	for i,v :=range m{
    		fmt.Println(i,v)
    	}
    

    4.取得对应key的value

    	m2:=m["name"]
    	fmt.Println(m2)
    

    5.删除元素

    	fmt.Println("_____________删除元素")
    	delete(m,"name")
    	fmt.Println(m)
    

    6.判断是否存在key

    value,ok:=m[key]

    7.除了slice,map,func的内建类型都可以作为key

    4.面向对象

    4.1 结构体和方法

    2019年11月01日13:46:19

    1.仅支持封装,不支持继承和多态。

    2.go没有class,只有struct

    3.不论地址还是结构本身,一律采用.来访问成员

    type treeNode struct {
    	value int
    	left,right *treeNode
    }
    
    func main() {
    	var root treeNode
    
    	root=treeNode{value:3}
    	root.left=&treeNode{value:10}
    	root.right=&treeNode{5,nil,nil}
    	root.right.right=new(treeNode)
    
    
    	fmt.Println(root)
    	
    }
    
    

    4.结构的创建

    image-20191101140701689
    //工厂函数
    func createNode(value int) *treeNode{
    	return &treeNode{value:value}
    }
    

    5.为结构定义方法

    image-20191101142201332
    //定义方法
    func (node treeNode) print() {
    	fmt.Print(node.value)
    }
    
    	root.print()
    

    6.方法的不同

    不带指针:就是拷贝一份数据,实际上不修改原来的值

    带指针:会把地址传过去

    //定义方法
    func (node treeNode) print() {
    	fmt.Println(node.value)
    }
    
    //带指针
    func (node *treeNode) setValue(value int){
    	node.value=value
    }
    
    func main() {
    	var root treeNode
    
    	root=treeNode{value:3}
    	root.left=&treeNode{value:10}
    	root.right=&treeNode{5,nil,nil}
    	root.right.right=new(treeNode)
    
    
    	//fmt.Println(root)
    	root.print()
    	root.setValue(200)
    	root.print()
    }
    

    image-20191101142035852

    7.源码

    node.go

    package tree
    
    import "fmt"
    
    type Node struct {
    	Value       int
    	Left, Right *Node
    }
    
    func (node Node) Print() {
    	fmt.Print(node.Value, " ")
    }
    
    func (node *Node) SetValue(value int) {
    	if node == nil {
    		fmt.Println("Setting Value to nil " +
    			"node. Ignored.")
    		return
    	}
    	node.Value = value
    }
    
    func CreateNode(value int) *Node {
    	return &Node{Value: value}
    }
    
    

    traversal.go

    package tree
    
    import "fmt"
    
    func (node *Node) Traverse() {
    	node.TraverseFunc(func(n *Node) {
    		n.Print()
    	})
    	fmt.Println()
    }
    
    func (node *Node) TraverseFunc(f func(*Node)) {
    	if node == nil {
    		return
    	}
    
    	node.Left.TraverseFunc(f)
    	f(node)
    	node.Right.TraverseFunc(f)
    }
    
    func (node *Node) TraverseWithChannel() chan *Node {
    	out := make(chan *Node)
    	go func() {
    		node.TraverseFunc(func(node *Node) {
    			out <- node
    		})
    		close(out)
    	}()
    	return out
    }
    
    

    entry.go

    package main
    
    import (
    	"fmt"
    
    	"imooc.com/ccmouse/learngo/tree"
    )
    
    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)
    
    	fmt.Print("In-order traversal: ")
    	root.Traverse()
    
    	fmt.Print("My own post-order traversal: ")
    	myRoot := myTreeNode{&root}
    	myRoot.postOrder()
    	fmt.Println()
    
    	nodeCount := 0
    	root.TraverseFunc(func(node *tree.Node) {
    		nodeCount++
    	})
    	fmt.Println("Node count:", nodeCount)
    
    	c := root.TraverseWithChannel()
    	maxNodeValue := 0
    	for node := range c {
    		if node.Value > maxNodeValue {
    			maxNodeValue = node.Value
    		}
    	}
    	fmt.Println("Max node value:", maxNodeValue)
    }
    
    

    4.2 包和封装

    2019年11月01日14:33:25

    封装

    1.名字一般使用CamelCase

    2.首字母大写: public

    3.首字母小写:private

    package tree
    
    import "fmt"
    
    type Node struct {
    	Value       int
    	Left, Right *Node
    }
    
    //工厂函数
    func createNode(value int) *Node {
    	return &Node{Value: value}
    }
    
    //定义方法
    func (node Node) Print() {
    	fmt.Println(node.Value)
    }
    
    //带指针
    func (node *Node) SetValue(value int){
    	node.Value =value
    }
    
    
    package main
    
    import "awesomeProject/src/tree"
    
    func main() {
    	var root tree.Node
    
    	root=tree.Node{Value: 3}
    	root.Left=&tree.Node{Value: 10}
    	root.Right=&tree.Node{5,nil,nil}
    	root.Right.Right=new(tree.Node)
    
    
    	//fmt.Println(root)
    	root.Print()
    	root.SetValue(200)
    	root.Print()
    }
    

    4.2 包

    4.每个目录一个包

    5.main包包含可执行入口

    6.为结构定义的方法必须放在同一个包内,但是可以是不同文件

    7.封装的好处:

    • 隐藏实现细节;
    • 可以对数据进行验证,保证数据安全合理。

    如何体现封装:

    • 对结构体中的属性进行封装;
    • 通过方法,包,实现封装。

    封装的实现步骤:

    • 将结构体、字段的首字母小写;
    • 给结构体所在的包提供一个工厂模式的函数,首字母大写,类似一个构造函数;
    • 提供一个首字母大写的 Set 方法(类似其它语言的 public),用于对属性判断并赋值;
    • 提供一个首字母大写的 Get 方法(类似其它语言的 public),用于获取属性的值。

    8.常用内置包

    1) fmt

    包 fmt 实现了格式化的 I/O 函数,这与 C 的 printf 和 scanf 类似。格式化短语派生于 C 。一些短语(%-序列)这样使用:

    2) io

    这个包提供了原始的 I/O 操作界面。它主要的任务是对 os 包这样的原始的 I/O 进行封装,增加一些其他相关,使其具有抽象功能用在公共的接口上。
    这个包实现了缓冲的 I/O。它封装于 io.Reader 和 io.Writer 对象,创建了另一个对象(Reader 和 Writer)在提供缓冲的同时实现了一些文本 I/O 的功能。

    4) sort

    sort 包提供了对数组和用户定义集合的原始的排序功能。
    strconv 包提供了将字符串转换成基本数据类型,或者从基本数据类型转换为字符串的功能。

    6) os

    os 包提供了与平台无关的操作系统功能接口。其设计是 Unix 形式的。
    sync 包提供了基本的同步原语,例如互斥锁。

    8) flag

    flag 包实现了命令行解析。
    encoding/json 包实现了编码与解码 RFC 4627 定义的 JSON 对象。

    10) html/template

    数据驱动的模板,用于生成文本输出,例如 HTML。
    将模板关联到某个上进行解析。模板内容指向数据结构的元素(通常结构的字段或者 map 的键)控制解析并且决定某个值会被显示。模板扫描结构以便解析,而“游标” @ 决定了当前位置在结构中的值。

    11) net/http

    net/http 实现了 HTTP 请求、响应和 URL 的解析,并且提供了可扩展的 HTTP 服务和基本的 HTTP 客户端。
    unsafe 包包含了 Go 程序中数据类型上所有不安全的操作。通常无须使用这个。

    13) reflect

    reflect 包实现了运行时反射,允许程序通过抽象类型操作对象。通常用于处理静态类型 interface{} 的值,并且通过 Typeof 解析出其动态类型信息,通常会返回一个有接口类型 Type 的对象。
    os/exec 包执行外部命令。

    4.3 扩展已有类型

    2019年11月01日14:49:06

    1.如何扩充系统类型或者别人的类型

    • 定义别名
    • 使用组合

    4.4 gopath

    2019年11月01日15:12:38

    1.

    image-20191101151647737

    2.查看gopath

    apple$ pwd
    /Users/apple/go/src/awesomeProject/src
    
     apple$ echo $GOPATH
    /Users/apple/go/src/awesomeProject/src:/Users/apple/go/src/awesomeProject
    :/Users/apple/go
    
     apple$ cat ~/.bash_profile
    PATH=$PATH:/usr/local/mysql/bin
    export GOPATH="/Users/apple/go"
    export PATH=$PATH:$GOPATH/bin
    export GOROOT=/usr/local/go
    
    

    3.

    image-20191101153930852 image-20191101155046820 image-20191101155109828

    2019年12月16日16:51:53

    END

  • 相关阅读:
    Spring 学习7 -事务
    Spring学习 6- Spring MVC (Spring MVC原理及配置详解)
    看秒杀系统的时候看到的关于并发队列的介绍,摘抄如下
    Spring 学习 3- AOP
    Spring学习-1 框架总览
    Spring 学习 5- task 定时任务
    JAVA锁机制-可重入锁,可中断锁,公平锁,读写锁,自旋锁,
    指定链接的样式的顺序
    css方法实现div固定浏览器底端
    文件中批量搜索字符串
  • 原文地址:https://www.cnblogs.com/oneapple/p/12049968.html
Copyright © 2011-2022 走看看