golang 中有判断切片中是否包含某元素的现成方法么?
不知道从何查起....阅读全文
不知道从何查起....阅读全文
欢迎来到 [Golang 系列教程](/subject/2)的第 13 个教程。 ## 什么是 map ? map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值。 ## 如何创建 map ? 通过向 `make` 函数传入键和值的类型,可以创建 map。`make(map[type of key]type of value)` 是创建 map 的语法。 ```go personSalary := make(map[string]int) ``` 上面的代码创建了一个名为 `personSalary` 的 map,其中键是 string 类型,而值是 int 类型。 map 的零值是 `nil`。如果你想添加元素到 nil map 中,会触发运行时 p...阅读全文
今天在群里看见有人写了一个InAarry方法,主要作用是判断一个元素是否在slice中,看完后,我感觉方法应该还有扩展的空间 于是自己重新写了一个Contains方法,可以支持 slice,array,map等类型 package main import ( "errors" "fmt" "reflect" ) // 判断obj是否在target中,target支持的类型arrary,slice,map func Contain(obj interface{}, target interface{}) (bool, error) { targetValue := reflect.ValueOf(target) switch reflect.TypeOf(target).Kind() { ca...阅读全文
结论:GoLang里对slice一定要谨慎使用append操作。cap未变化时,slice是对数组的引用,并且append会修改被引用数组的值。append操作导致cap变化后,会复制被引用的数组,然后切断引用关系。 代码和注释如下: package main import ( "fmt" ) func main() { array := []int{10, 11, 12, 13, 14} slice := array[0:4] // slice是对array的引用 fmt.Println("array: ", array) // array: [20 21 12 13 14] fmt.Println("slice: cap=", cap(slice), ", value=", slice)...阅读全文
golang的container包中提供了heap容器,这个容器可以用来做什么,又是怎么做到的呢?本文从golang 1.9.3的源码出发,说明了堆、heap包、heap包的用途、heap包的实现。 1 heap是什么 首先先来解释一下堆(Heap)是什么。 据维基百科 堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。 逻辑定义:n个元素序列{k1, k2… ki…kn},当且仅当满足下列关系时称之为堆: (ki <= k2i, ki <= k2i+...阅读全文
作为现代10后语言的golang(12年正式发布)。Golang的标准库提供了高级的数据结构List。具体在包container/list。该包里主要有两个数据结构组成:“Element”、“List”。其中“Element”相当于CPP里面的"iterator",其有Prev和Next方法用于得到前一个或者下一个迭代器,迭代器的间接引用直接使用其成员Value。1 创建一个List对象来感受一下l := list.New() l.PushBack("one") l.PushBack(2) fmt.Println(l)上面的代码可以得到如下的输出:&{{0x2081a21b0 0x2081a21e0
一 、==========================array 数组=================================== 索引只能是 int 整数型 所以不管几维数组 索引都是 整数 slice 是动态数组 索引也是 整数型 map为key 所以 可以为 整数 也可以为 字符串型 注意slice和数组在声明时的区别:声明数组时,方括号内写明了数组的长度或使用...自动计算长度,而声明slice时,方括号内没有任何字符。 arr1 := [10]int{1,2,3,4} //数组,长度为10,只有4个元素指定,其它的元素值默认为0 arr2 := [...]string{"a","b","c"} //数组,长度自适应,这里长度为3 s1 := []int{1,2,3,4...阅读全文
package main import ( "encoding/xml" "fmt" "mahonia" "os" "strconv" "text/template" ) type Attribute struct { Name string Value string } type Token struct { Name string Attributes []Attribute Tokens []Token } type Result struct { Root Token } var result = Result{} func main() { if !parse("config.xml") { return } if !output("code_h.tpl", "code.h") {...阅读全文
package main import "fmt" func main() { slice1 := []byte{1, 2, 3, 4, 5} slice2 := []byte{5, 4, 3} copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中 fmt.Printf("%x\n",slice1) fmt.Printf("%x\n",slice2) copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置 fmt.Printf("%x\n",slice1) fmt.Printf("%x\n",slice2) var md5code [16]byte arybyte := md5code[0:16] ...阅读全文
go中container中list的使用详解 1. func New() *List{} 初始化一个列表,返回类型为一个list对象 a := list.New() # 在函数内部 a = list.New() 输出: &{{0xc00006a300 0xc00006a300
数组: 语法: //value := [数据长度]类型 {} arr := [1]string{"1"}// 声明并且赋值 arr = [1]string{}// 声明未赋值 arr[0]="1" 数组类型的值(以下简称数组)的长度是固定的数组的长度在声明它的时候就必须给定,并且在之后不会再改变。可以说,数组的长度是其类型的一部分(数组的容量永远等于其长度,都是不可变的) 切片: 语法: //value := []类型 {} // 创建长度容量都为0的切片 value :=[]string{}// []string{"1"} 长度容量为1的切片 value :=append(value,"1") //数据转切片 arr := [1]string{"1"} slice :=arr[:] // ...阅读全文
Slice是长度可变的元素序列(数组不可变),每个元素都有相同的类型。slice类型写作[]T,其中T代表slice中的元素类型;slice和数组写法很像,只是没有指定长度。 数组和slice之间的联系非常紧密。slice是非常轻量的数据结构,它是引用类型,指向底层的一个数组,该数组被称之为slice的底层数组,slice可以访问底层数组的某个子序列,也可以访问整个数组。一个slice由三个部分组成:指针、长度、容量,指针指向了slice中第一个元素对应的底层数组元素的地址,因为slice未必是从数组第一个元素开始,因此slice中的第一个元素未必是数组中的第一个元素。长度对应slice中的元素数目,长度是不能超过容量的;容量一般是从slice中第一个元素对应底层数组中的开始位置,到底层数组...阅读全文
使用时元素需实现ELEM接口
package main import ( "os" "io" "fmt" "encoding/xml" "strconv" ) type Config map[string]map[string]string var config = make(Config) type Class struct { XMLName xml.Name `xml:"class"` //xml元素名称 Id int `xml:"id,attr"` // Pers []Persion `xml:"persion"` // Desc string `xml:",innerxml"` // } type Persion struct { XMLName xml.Name `xml:"persion"` Id int ...阅读全文
## 注意事项 ### 数组定义长度后就固定了,没法删除和添加新元素 ###切片添加和删除 ```go package main import ( "fmt" ) func main() { v1 := []int{1, 2} //len=2, cap=2 v1 = append(v1,6,7) //增加一个 v1 = append(v1,6,7,8) //增加多个 fmt.Println(v1,len(v1), cap(v1)) //[1 2 6 7 6 7 8] len=7,cap=8 cap按照初始化的cap倍数增加 //删除一个元素 v2 := []int{1, 2, 3 ,4 ,5, 6} fmt.Println(v2,len(v2), cap(v2)) //[1 2 3 4 5 ...阅读全文
import ( "errors" ) //循环队列结构体(顺序存储) type CirularQueue struct { elem []ElemType //储存的数据 front int //头指针 rear int //尾指针 } //初始化循环队列 func InitCQueue() *CirularQueue { cqueue := new(CirularQueue) cqueue.elem = make([]ElemType, MAXSIZE) cqueue.front = 0 cqueue.rear = 0 return cqueue } //清空循环队列 func (cqueue *CirularQueue) ClearCQueue() { cqueue.front = 0...阅读全文
1 func binarySearch(nodes []*node, word Text) (int, bool) { 2 start := 0 3 end := len(nodes) - 1 4 5 // 特例: 6 if len(nodes) == 0 { 7 // 当slice为空时,插入第一位置 8 return 0, false 9 } 10 compareWithFirstWord := bytes.Compare(word, nodes[0].word) 11 if compareWithFirstWord < 0 { 12 // 当要查找的元素小于首元素时,插入第一位置 13 return 0, false 14 } else if compareWithFirstWord ...阅读全文
杨辉三角的样式如下: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 它的特征是,每一行的最左边和最右边的元素都是1,而其它元素等于它上方“肩膀”上的两个元素之和。 使用Go语言打印杨辉三角: package test import ( "fmt" ) //行数 const LINES int = 8 //杨辉三角 func ShowYangHuiTriangle() { nums := []int{} for i := 0; i < LINES; i++ { //补空白 for j := 0; j < (LINES - i); j++ { fmt.Print(" ") } fo...阅读全文
首先之前关于 slice 的 append 理解: 每次 append 操作都会检查 slice 是否有足够的容量,如果足够会直接在原始数组上追加元素并返回一个新的 slice,底层数组不变而若容量不够,会创建一个新的容量足够的底层数组,先将之前数组的元素复制过来,再将新元素追加到后面,然后返回新的 slice,底层数组改变而这里对新数组的容量定义是按 乘以2 的机制增加 而今天看到关于 Golang 切片的底层结构即 reflect.SliceHeader 时,发现 append 的扩容并不完全是2倍增长,源码如下(Go version 1.13): // grow grows the slice s so that it can hold extra more values, alloc...阅读全文
package main import "fmt" type Object interface {} //节点 type Node struct { data Object next *Node } //单向链表 type List struct { head *Node tail *Node size uint64 } //初始化 func(list *List) Init(){ (*list).size = 0 // 此时链表是空的 (*list).head = nil // 没有头 (*list).tail = nil // 没有尾 } //向尾部添加数据 func (list *List) Append(node *Node) bool { if node == nil { retu...阅读全文
package main import ( "encoding/xml" "fmt" "mahonia" "os" "strconv" "text/template" ) type Attribute struct { Name string Value string Type string } type Token struct { Name string IsArray string Num int Attributes map[string]*Attribute Tokens map[string]*Token } type Result struct { Root Token } var result = Result{} var g_tabNum = 0 var g_classVe...阅读全文
go的map和java的map在操作上区别不大。 不过有些内容还是不一样的。 1. 检测某个键是否存在: elem, ok = m[key] 如果 key 在 m 中,`ok` 为 true 。否则, ok 为 `false`,并且 elem 是 map 的元素类型的零值。 2. 如果某个键不存在,直接用这个键读value的话,返回的是 map 的元素类型的零值 例如: m := make(map[string]int) m["Answer"] = 42 fmt.Println("The value:", m["Answer"]) delete(m, "Answer") fmt.Println("The value:", m["Answer"]) 运行结果为: The value: 42 T...阅读全文
我想定义一个 ``` type mytype []string var arr mytype =mytype([]string{"123","abc"}) ``` 当然,为的就是增加一些方法。 但是问题来了,如果又来了一些元素要加入我自己定义的这个arr,应该怎么加?只靠强转...阅读全文
简介 在上一篇文章中我们介绍了如何使用gjson快速读取 JSON 串中的值。为了内容的完整性,今天我们介绍一下如何使用sjson快速设置 JSON 串中的值。 快速使用 先安装: $ go get github.com/tidwall/sjson 后使用: package main import ( "fmt" "github.com/tidwall/sjson" ) const json = `{"name":{"first":"li","last":"dj"},"age":18}` func main() { value, _ := sjson.Set(json, "name.last", "dajun") fmt.Println(value) } 上面代码通过sjson.Set()将...阅读全文
但凡IT江湖侠士,算法与数据结构为必修之课。早有前辈已经明确指出:程序=算法+数据结构 。要想在之后的江湖历练中通关,数据结构必不可少。数据结构与算法相辅相成,亦是阴阳互补之法。 开篇 说道数组,几乎每个IT江湖人士都不陌生,甚至过半人还会很自信觉的它很简单。 的确,在菜菜所知道的编程语言中几乎都会有数组的影子。不过它不仅仅是一种基础的数据类型,更是一种基础的数据结构。如果你觉的对数组足够了解,那能不能回答一下: 数组的本质定义? 数组的内存结构? 数组有什么优势? 数组有什么劣势? 数组的应用场景? 数组为什么大部分都从0开始编号? 数组能否用其他容器来代替,例如c#中的List
但凡IT江湖侠士,算法与数据结构为必修之课。早有前辈已经明确指出:程序=算法+数据结构 。要想在之后的江湖历练中通关,数据结构必不可少。数据结构与算法相辅相成,亦是阴阳互补之法。 开篇 说道数组,几乎每个IT江湖人士都不陌生,甚至过半人还会很自信觉的它很简单。的确,在菜菜所知道的编程语言中几乎都会有数组的影子。不过它不仅仅是一种基础的数据类型,更是一种基础的数据结构。如果你觉的对数组足够了解,那能不能回答一下: 数组的本质定义? 数组的内存结构? 数组有什么优势? 数组有什么劣势? 数组的应用场景? 数组为什么大部分都从0开始编号? 数组能否用其他容器来代替,例如c#中的List
最近尝试在 B 站录些小视频,我的 B 站主页。录视频当是为了彻底搞懂某个知识点的最后一步吧,同时也希望能习得一些额外的能力。在讲 Go 如何实现 bitset 的时候,发现这块内容有点难讲。思考后,我决定通过文字辅以视频的方式说明,于是就写了这篇文章。 相关代码已经放在了 github,地址如下:go-set-example 如果发现有什么不妥的地方,欢迎大佬们指正,感谢。 bitset 结构 之前我已经写过一篇题为 Go 中如何使用 Set 的文章,其中介绍了 bitset 一种最简单的应用场景,状态标志位,顺便还提了下 bitset 的实现思路。 状态标志和一般的集合有什么区别呢? 我的总结是主要一点,那就是状态标志中元素个数通常是固定的。而一般的集合中,元素个数通常是动态变化的。这...阅读全文
# package slicelement Go library for finding element in slice type or operating set including union, interaction and difference. not only it supports the buildin types which includes `[]int/[]*int`, `[]float/[]*float`, `[]string/[]*string`, but also it supports `[]struct/[]*struct` . The latter is very important and convenient ## Installati...阅读全文
一:插入排序 1:算法描述 从第一个元素开始,该元素可以认为已经被排序 取出下一个元素,在已经排序的元素序列中从后向前扫描 如果该元素(已排序)大于新元素,将该元素移到下一位置 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 将新元素插入到该位置后 重复步骤2~5 2:代码实现 func insertSort(p []int) { for i := 1; i < len(p); i++ { for j := i - 1; j >= 0 && p[j+1] < p[j]; j-- { p[j+1], p[j] = p[j], p[j+1] } } } 二:冒泡排序 1:算法描述 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的...阅读全文
一:插入排序 1:算法描述 从第一个元素开始,该元素可以认为已经被排序 取出下一个元素,在已经排序的元素序列中从后向前扫描 如果该元素(已排序)大于新元素,将该元素移到下一位置 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 将新元素插入到该位置后 重复步骤2~5 2:代码实现 func insertSort(p []int) { for i := 1; i < len(p); i++ { for j := i - 1; j >= 0 && p[j+1] < p[j]; j-- { p[j+1], p[j] = p[j], p[j+1] } } } 二:冒泡排序 1:算法描述 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的...阅读全文
切片切片是一种数据结构,这种数据结构便于使用和管理数据集合。切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数 append 来实现的。这个函数可以快速且高效地增长切片。还可以通过对切片再次切片来缩小一个切片的大小。因为切片的底层内存也是在连续块中分配的,所以切片还能获得索引、迭代以及为垃圾回收优化的好处。内部实现切片是一个很小的对象,对底层数组进行了抽象,并提供相关的操作方法。切片有 3 个字段的数据结构,这些数据结构包含 Go 语言需要操作底层数组的元数据.如下图这 3 个字段分别是指向底层数组的指针、切片访问的元素的个数(即长度)和切片允许增长到的元素个数(即容量)。创建和初始化Go 语言中有几种方法可以创建和初始化切片。是否能提前知道切片需要的容量...阅读全文
container/list 这个包包含了两个公开的程序实体:List和Element。前者实现了一个双向链表(以下简称链表),而后者则代表了链表中元素的结构。 //这是一个list中存储的元素 type Element struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Ba...阅读全文
一个 slicelement 包,用于查找一个元素,是否在列表中存在。支持 int、string、float 内置类型,也支持 struct 类型。比如:查找一个指定字段的元素值,是否在 []struct 中存在 我们经常遇到 append(data, element) 往列表中添加元素,如果 data 不存在该元素,则添加。还有一种情况也经常遇到的是,一个 []struct 数据复杂类型,判断 struct 中某个字段值是否存在,不存在则添加。 该 slicelement 包,支持这种查找,方便和节约了大家的宝贵时间 形如: slicelement.Contains([]string{"Joe", "David", "Bruce Lee...阅读全文
最近尝试在 B 站录些小视频,我的 B 站主页。录视频当是为了彻底搞懂某个知识点的最后一步吧,同时也希望能习得一些额外的能力。在讲 Go 如何实现 bitset 的时候,发现这块内容有点难讲。思考后,我决定通过文字辅以视频的方式说明,于是就写了这篇文章。 相关代码已经放在了 github,地址如下:go-set-example 如果发现有什么不妥的地方,欢迎大佬们指正,感谢。 bitset 结构 之前我已经写过一篇题为 Go 中如何使用 Set 的文章,其中介绍了 bitset 一种最简单的应用场景,状态标志位,顺便还提了下 bitset 的实现思路。 状态标志和一般的集合有什么区别呢? 我的总结是主要一点,那就是状态标志中元素个数通常是固定的。而一般的集合中,元素个数通常是动态变化的。这会...阅读全文
五种基础排序算法对比 五种基础排序算法对比 1:冒泡排序 算法描述 比较相邻的元素。如果第一个比第二个大,就交换它们两个; 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数; 针对所有的元素重复以上的步骤,除了最后一个; 重复步骤1~3,直到排序完成。 动图演示 冒泡排序动图演示 代码演示 func bubbleSort(arr [6]int) { for i := 0; i < len(arr)-1; i++ { for j := 0; j < len(arr)-i-1; j++ { if arr[j] > arr[j+1] { temp := arr[j] arr[j] = arr[j+1] arr[j+1] = temp } } } fmt....阅读全文
双向链表的定义 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 这里记录一下自己学习理解的过程 图解 [图片上传失败...(image-afe880-1531019243291)] Go的源码实现 1.首先看一下链表中存储的元素(Element)的定义: // 双向链表的一个元素 type Element struct { // 前驱指针和后继指针 prev, next *Element // 该元素属于哪个链表list list *List // 该元素存储的值 Value interface{} } 2.为Element这个结构体定义...阅读全文
package main import ( "fmt" ) func main() { s := []interface{}{1, 2, 3, 4, 5, 6, 7, 8} HERE: for k, v := range s { if v == 4 || v == 6 || v == 7 { // temp := s[k+1:] -> error fmt.Println("k", k) temp := make([]interface{}, 0) for _, v := range s[k+1:] { temp = append(temp, v) } fmt.Println("temp1", temp) s = append(s[:k], "(") fmt.Println(s) s = ap...阅读全文
本文系第十二篇Golang语言学习教程 上一节学习了golang数组的知识,这节开始学习切片的概念应用;首先来看多维数组 多维数组 Go语言可以创建多维数组: package main import "fmt" func test(a [3][2]string) { //定义函数test,输入值为多维二维数组 a for _, v1 := range a { for _, v2 :=range v1 { fmt.Printf("%s ", v2) //两次循环得到其中一个值并输出 } fmt.Println("\n") } } func main() { a := [3][2]string{ //定义一个二维数组 {"1x1", "1x2"}, {"2x1", "2x2"}, {"3x1",...阅读全文
问题描述 75. Sort ColorsGiven an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. 冒泡排序 算法描述 1 遍历待排序序列2 比较相邻两个数,不相等则交换位置把大数放在小数后面3 重复以上步骤,直到待排序序列为...阅读全文
关于ring,可以参考Golang源码 container 系列一 ring环形链表,list也是个链表,但是稍有差别。 参考【Go】笔记五 | container包中的list与ring 一、源码对比 type Ring struct { next, prev *Ring Value interface{} } // Element is an element of a linked list. type Element struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is ...阅读全文
概述 切片是基于数据中连续片段的引用,是一个引用类型。与数组相比,切片的长度可以在运行时修改,可以将切片看作是长度可变的动态数组。 切片的实现是由一个底层数组以及其上面的动态位置,尺寸来实现。由指向底层数组的指针、访问元素的个数(即长度length)和允许增长到的元素个数(即容量capacity)组成。 指针ptr,用于指向切片在底层数组的起始位置。 尺寸len,用于记录切片内元素数量。 容量cap,当前切片最大容量,也就是底层数组的容量,可以动态分配。 创建和初始化切片 1. make和切片字面量 使用内置函数make()创建切片: var slice []type = make([]type, len, cap) 也可以简写: slice := make([]type, len, cap...阅读全文
开发十年,就只剩下这套Java开发体系了 >>> m1 := map[string]string{ "name":"falcon", "gender":"male", } if name, ok := m1["name"]; ok { //判断一个key是否存在,不存在时ok为false fmt.Println("key name exists ,value: " + name) } else { fmt.Println("key not exists") } delete(m1, "name") //删除一个元素 if name, ok := m1["name"]; ok { //判断一个key是否存在,不存在时ok为false fmt.Println("key name exists ,...阅读全文
以下用法中,类型均使用 int64 做为示例,不处理 interface 。 代码只是展示实现思路,不一定完善。 合并两个有序切片,新切片仍然有序 func MergeSortedSlice(s1, s2 []int64) []int64 { // 从末尾元素开始遍历 i := len(s1) - 1 j := len(s2) - 1 // 合并后的长度 newLen := len(s1) + len(s2) // 合并后的索引,也从末尾元素开始 newIdx := newLen - 1 // 创建一个新切片,代表合并后的 newS := make([]int64, newLen) // 将 s1 的内容拷贝到新切片 for k, v := range s1 { newS[k] = v } ...阅读全文
数组: 语法: //value := [数据长度]类型 {} arr := [1]string{"1"}// 声明并且赋值 arr = [1]string{}// 声明未赋值 arr[0]="1" 数组类型的值(以下简称数组)的长度是固定的数组的长度在声明它的时候就必须给定,并且在之后不会再改变。可以说,数组的长度是其类型的一部分(数组的容量永远等于其长度,都是不可变的) 切片: 语法: //value := []类型 {} // 创建长度容量都为0的切片 value :=[]string{}// []string{"1"} 长度容量为1的切片 value :=append(value,"1") //数据转切片 arr := [1]string{"1"} slice :=arr[:] // ...阅读全文
注:本文是对golang-101-hacks中文翻译。 往切片中增加数时,如果切片的所关联的数组没有足够的空间,会重新开辟一个新的数组空间。同时将原先数组中的元素复制到这个新数组对应的内存中,将新添加数据加到数组尾部。因此,在使用Go内置的append函数时,需要小心谨慎,始终牢记“数组可能已经更改”的思想! 下面刻意营造的的例子来说明我们需要注意的点: package main import ( "fmt" ) func addTail(s []int) { var ns [][]int for _, v := range []int{1, 2} { ns = append(ns, append(s, v)) } fmt.Println(ns) } func main() { s1 := ...阅读全文
链表 Go语言的链表实现在其标准库的container/list代码包中。 这个包包含了2个程序实体: List : 实现了一个双向链表 Element : 代表了链表中元素的结构 操作链表 移动链表里的元素: func (l *List) MoveBefore(e, mark *Element) // 把元素e移动到mark元素的前面 func (l *List) MoveAfter(e, mark *Element) // 把元素e移动到mark元素的后面 func (l *List) MoveToFront(e *Element) // 把元素e移动到链表的最前端 func (l *List) MoveToBack(e *Element) // 把元素e移动到链表的最后端 上面的方法都...阅读全文
数组和切片 数组(array)类型和切片(slice)类型: 相同:都属于集合类的类型,它们的值都可以用来存储某一种类型的值(或者说元素)。 不同:数组的长度是固定的,而切片是可变长的。 长度数组的长度在声明的时候必须确定,并且之后不会再变。长度是其类型的一部分。 比如:[1]string 和 [2]string 是两个不同的类型。 切片的长度是可以随着其中元素的增长而增长的,但是不会随着元素的减少而减少。 底层数组可以把切片看做是对数组的一层简单的封装,每个切片的底层数据结构中,一定会包含一个数组。这个数组可以被叫做切片的底层数组。而切片可以被看做是对数组的某个连续片段的引用。 值类型、引用类型 切片属于引用类型,数组属于值类型引用类型: 切片 字典 管道 函数 值类型: 数组 结构体 长...阅读全文
1. 切片底层实现 1.1 切片简介 Go语言中的切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数append来实现的,还可以通过对切片再次切片来缩小一个切片的大小。因为切片在内存中是连续的,所以切片还能获得索引、迭代以及垃圾回收优化的好处。 1.2 切片底层实现 切片的底层实现包含3个字段:指向底层数组的指针、切片访问的元素的个数(长度)、切片允许增长到的元素的个数(容量),如下图所示。切片可以理解为对底层数组进行了抽象,并提供了相关的操作方法。 2. 切片的基础操作 2.1 创建和初始化 可以通过make、切片字面量来创建和初始化切片,也可以利用现有数组或切片直接创建切片(Go语言中的引用类型(slice、map、chan)不...阅读全文
Java中生产者与消费者问题的演变队列阻塞(BlockingQueue)关于Blocking Queue的更多细节Java中生产者与消费者问题的演变原文链接:https://dzone.com/articles/the-evolution-of-producer-consumer-problem-in-java作者: Ioan Tinca译者: liumapp想要了解更多关于Java生产者消费者问题的演变吗?那就看看这篇文章吧,我们分别用旧方法和新方法来处理这个问题。生产者消费者问题是一个典型的多进程同步问题。对于大多数人来说,这个问题可能是我们在学校,执行第一次并行算法所遇到的第一个同步问题。虽然它很简单,但一直是并行计算中的最大挑战 - 多个进程共享一个资源。问题陈述生产者和消费者两个程...阅读全文
13. Maps 什么是 map ? map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值。 如何创建 map ? 通过向 make 函数传入键和值的类型,可以创建 map。make(map[type of key]type of value) 是创建 map 的语法。 personSalary := make(map[string]int) 上面的代码创建了一个名为 personSalary 的 map,其中键是 string 类型,而值是 int 类型。 map 的零值是 nil。如果你想添加元素到 nil map 中,会触发运行时 panic。因此 map 必须使用 make 函数初始化。 package main import ( "fmt"...阅读全文