go语言核心36讲要点概括(6-10)

06 | 程序实体的那些事儿 (下)

package main

import ."fmt"

var container = []string{"0","1","2"}

func main()  {
	container := map[int]string{0:"zero",1:"one",2:"two"}
	//输出one
	Println(container[1])
}

如何判断container类型

value,ok  :=  interface{}(container).([]string)

它包括了用来把container变量的值转换为空接口值的interface{}(container)。 (如果container是接口类型,直接是

container.([]string))

以及一个用于判断前者的类型是否为切片类型 []string 的.([]string)。

如果ok是true,那么被判断的值将会被自动转换为[]string类型的值,并赋给变量value,否则value将被赋予nil(即“空”)。

interface{}代表空接口,任何类型都是它的实现类型,任何类型的值都可以很方便地被转换成空接口的值

一对不包裹任何东西的花括号,除了可以代表空的代码块之外,还可用于表示不包含任何内容的数据结构(或者说数据类型)。

package main
import (
	"fmt"
)
var container = []string{"zero", "one", "two"}

func main() {

	container := map[int]string{0: "zero", 1: "one", 2: "two"}

	// 方式1。
	_, ok1 := interface{}(container).([]string)
	_, ok2 := interface{}(container).(map[int]string)

	if !(ok1 || ok2) {
		fmt.Printf("Error: unsupported container type: %T\n", container)
		return
         }

	fmt.Printf("The element is %q. (container type: %T)\n",
		container[1], container)

	// 方式2。
	elem, err := getElement(container)
	if err != nil {
		fmt.Printf("Error: %s\n", err)
		return
	}

	fmt.Printf("The element is %q. (container type: %T)\n",

		elem, container)
}


func getElement(containerI interface{}) (elem string, err error) {

	switch t := containerI.(type) {
	case []string:
		elem = t[1]

	case map[int]string:
		elem = t[1]

	default:
		err = fmt.Errorf("unsupported container type: %T", containerI)
		return
	}
	return
}

数字与字符转换

package main

import (
	"fmt"
	"strconv"
)

func main()  {
	fmt.Println(string(-1))
	a := 97
	fmt.Println(string(a))
	as := strconv.Itoa(a)
	fmt.Println(string(as))
	//输出结果
	//�
	//a
	//97
}

07 | 数组和切片

数组长度一定,切片长度会随着元素增加而增加,但长度不会减少

Go 中数组赋值和函数传参都是值复制的

引用类型:切片,字典,通道,函数类型等

值类型:基础数据类型,结构体类型

判断是值传递还是引用传递,只需要看他的类型就行了。

//len = cap = 8
s3 := []int{1, 2, 3, 4, 5, 6, 7,8}

//[3,6)
// len = 3
//cap = 8 - 3 = 5 (可以向右扩展的长度,因为起始索引是3  所以减3)
s4 = s3[3:6]

扩容问题

08 | container包中的那些容器

list与ring   看源码

09 | 字典的操作和约束

键不能是函数,字典,切片类型  因为键要支持 == 判断

如果是interface   键类型具体赋值是以上3中类型  会引发panic

哈希桶里的结构是,“键的哈希值-内部结构”对的集合,这个内部结构的结构是“键1元素1键2元素2键3元素3”,是一块连续的内存。在通过键的哈希值定位找到哈希桶和那个“键的哈希值-内部结构”对之后,就开始在这个内部结构里找有没有这个键

非原子操作需要加锁, map并发读写需要加锁,map操作不是并发安全的,判断一个操作是否是原子的可以使用 go run race 命令做数据的竞争检测

10 | 通道的基本操作

通道之前取值和放入值都是并行的

package main



func main() {

	// 示例1。

	ch1 := make(chan int, 1)

	ch1 <- 1

	//ch1 <- 2 // 通道已满,因此这里会造成阻塞。



	// 示例2。

	ch2 := make(chan int, 1)

	//elem, ok := <-ch2 // 通道已空,因此这里会造成阻塞。

	//_, _ = elem, ok

	ch2 <- 1



	// 示例3。

	var ch3 chan int

	//ch3 <- 1 // 通道的值为nil,因此这里会造成永久的阻塞!

	//<-ch2 // 通道的值为nil,因此这里会造成永久的阻塞!

	_ = ch3

}

通道接收方可以有两个参数,第一个表示值,第二个是bool类型  表示通道是否关闭

接收方在通道关闭后  任然可以接收到存在于通道里的数据,由于这个特性,关闭通道最好在发送方关闭

猜你喜欢

转载自blog.csdn.net/qq_38020553/article/details/82492879
今日推荐