Go 1.21中新增的 slices
包中提供了很多與切片相關(guān)的函數(shù),適用于任意類型的切片。
本文內(nèi)容來自官方文檔
BinarySearch
函數(shù)簽名如下:
func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)
BinarySearch
在已排序的切片中搜索 target
并返回找到 target
的位置,或者 target
在排序順序中出現(xiàn)的位置;它還返回一個(gè)布爾值,表示是否確實(shí)在切片中找到了目標(biāo)。切片必須按升序排序。
示例:文章來源:http://www.zghlxwxcb.cn/news/detail-710550.html
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
n, found := slices.BinarySearch(names, "Vera")
fmt.Println("Vera:", n, found) // Vera: 2 true
n, found = slices.BinarySearch(names, "Bill")
fmt.Println("Bill:", n, found) // Bill: 1 false
}
BinarySearchFunc
函數(shù)簽名如下:
func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)
BinarySearchFunc
的工作方式類似于BinarySearch
,但使用自定義比較函數(shù)。切片必須按遞增順序排序,其中“遞增”由cmp
定義。如果切片元素與目標(biāo)匹配,則cmp
應(yīng)返回0
;如果切片元素在目標(biāo)之前,則返回負(fù)數(shù);如果切片元素在目標(biāo)之后,則返回正數(shù)。cmp
必須實(shí)現(xiàn)與切片相同的排序,這樣如果cmp(a, t) < 0
且cmp(b, t) >= 0
,則切片中a
必須位于b
之前。
示例:
package main
import (
"cmp"
"fmt"
"slices"
)
func main() {
type Person struct {
Name string
Age int
}
people := []Person{
{"Alice", 55},
{"Bob", 24},
{"Gopher", 13},
}
n, found := slices.BinarySearchFunc(people, Person{"Bob", 0}, func(a, b Person) int {
return cmp.Compare(a.Name, b.Name)
})
fmt.Println("Bob:", n, found) // Bob: 1 true
}
Clip
函數(shù)簽名如下:
func Clip[S ~[]E, E any](s S) S
Clip
從切片中刪除未使用的容量,返回s[:len(s):len(s)]
。
Clone
函數(shù)簽名如下:
func Clone[S ~[]E, E any](s S) S
Clone
返回切片的副本。使用賦值來復(fù)制元素,因此這是淺拷貝。
Compact
函數(shù)簽名如下:
func Compact[S ~[]E, E comparable](s S) S
Compact
用單個(gè)副本替換連續(xù)運(yùn)行的相同元素。這類似于Unix
上的uniq
命令。Compact
修改切片s
的內(nèi)容并返回修改后的切片,該切片的長度可能更小。當(dāng)Compact
總共丟棄m
個(gè)元素時(shí),它可能不會(huì)修改元素s[len(s)-m:len(s)]
。如果這些元素包含指針,可能要考慮將這些元素清零,以便它們引用的對象可以被回收。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
seq := []int{0, 1, 1, 2, 3, 5, 8}
seq = slices.Compact(seq)
fmt.Println(seq) // [0 1 2 3 5 8]
}
CompactFunc
函數(shù)簽名如下:
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S
CompactFunc
類似于Compact
,但使用相等函數(shù)來比較元素。對于比較相等的元素運(yùn)行,CompactFunc
保留第一個(gè)。
示例:
package main
import (
"fmt"
"slices"
"strings"
)
func main() {
names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
names = slices.CompactFunc(names, func(a, b string) bool {
return strings.ToLower(a) == strings.ToLower(b)
})
fmt.Println(names) // [bob alice Vera]
}
Compare
函數(shù)簽名如下:
func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int
Compare
對每對元素使用cmp.Compare
來比較s1
和s2
的元素。從索引0
開始按順序比較元素,直到一個(gè)元素不等于另一個(gè)元素。返回第一個(gè)不匹配元素的比較結(jié)果。如果兩個(gè)切片在其中一個(gè)結(jié)束之前都相等,則認(rèn)為較短的切片小于較長的切片。如果s1 == s2
,結(jié)果為0
;如果s1 < s2
,結(jié)果為-1
;如果s1 > s2
,結(jié)果為+1
。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
fmt.Println("Equal:", slices.Compare(names, []string{"Alice", "Bob", "Vera"})) // Equal: 0
fmt.Println("V < X:", slices.Compare(names, []string{"Alice", "Bob", "Xena"})) // V < X: -1
fmt.Println("V > C:", slices.Compare(names, []string{"Alice", "Bob", "Cat"})) // V > C: 1
fmt.Println("3 > 2:", slices.Compare(names, []string{"Alice", "Bob"})) // 3 > 2: 1
}
CompareFunc
函數(shù)簽名如下:
func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int
CompareFunc
類似于Compare
,但對每對元素使用自定義比較函數(shù)。結(jié)果是cmp
的第一個(gè)非零結(jié)果;如果cmp
始終返回0
:
- 如果
len(s1) == len(s2)
,則結(jié)果為0
; - 如果
len(s1) < len(s2)
,則結(jié)果為-1
; - 如果
len(s1) > len(s2)
,則結(jié)果為+1
。
示例:
import (
"cmp"
"fmt"
"slices"
"strconv"
)
func main() {
numbers := []int{0, 43, 8}
strings := []string{"0", "0", "8"}
result := slices.CompareFunc(numbers, strings, func(n int, s string) int {
sn, err := strconv.Atoi(s)
if err != nil {
return 1
}
return cmp.Compare(n, sn)
})
fmt.Println(result) // 1
}
Contains
函數(shù)簽名如下:
func Contains[S ~[]E, E comparable](s S, v E) bool
Contains
返回v
是否存在于s
中。
ContainsFunc
函數(shù)簽名如下:
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool
ContainsFunc
返回s
中是否至少有一個(gè)元素e
滿足f(e)
。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, -10, 8}
hasNegative := slices.ContainsFunc(numbers, func(n int) bool {
return n < 0
})
fmt.Println("Has a negative:", hasNegative) // Has a negative: true
hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
return n%2 != 0
})
fmt.Println("Has an odd number:", hasOdd) // Has an odd number: false
}
Delete
函數(shù)簽名如下:
func Delete[S ~[]E, E any](s S, i, j int) S
Delete
從s
中刪除元素s[i:j]
,返回修改后的切片。如果s[i:j]
不是s
的有效切片,則產(chǎn)生panic
。刪除的時(shí)間復(fù)雜度為O(len(s)-j)
,因此如果必須刪除許多項(xiàng),最好通過一次調(diào)用將它們?nèi)縿h除,而不是一次刪除一項(xiàng)。刪除可能不會(huì)修改元素s[len(s)-(j-i):len(s)]
。如果這些元素包含指針,還需要考慮將這些元素歸零,以便它們引用的對象可以被回收。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
letters := []string{"a", "b", "c", "d", "e"}
letters = slices.Delete(letters, 1, 4)
fmt.Println(letters) // [a e]
}
DeleteFunc
函數(shù)簽名如下:
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S
DeleteFunc
從s
中刪除函數(shù)del(e)
返回true
的所有元素,并返回修改后的切片。當(dāng)DeleteFunc
刪除m
個(gè)元素時(shí),它可能不會(huì)修改元素s[len(s)-m:len(s)]
。如果這些元素包含指針,還需要考慮將這些元素歸零,以便它們引用的對象可以被回收。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
seq := []int{0, 1, 1, 2, 3, 5, 8}
seq = slices.DeleteFunc(seq, func(n int) bool {
return n%2 != 0 // delete the odd numbers
})
fmt.Println(seq) // [0 2 8]
}
Equal
函數(shù)簽名如下:
func Equal[S ~[]E, E comparable](s1, s2 S) bool
Equal
報(bào)告兩個(gè)切片是否相等:長度相同且所有元素相等,返回true
。如果長度不同,返回false
。否則,按遞增的索引順序比較元素,并且比較在第一個(gè)不相等的對處停止。浮點(diǎn)NaN
不被視為相等。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, 8}
fmt.Println(slices.Equal(numbers, []int{0, 42, 8})) // true
fmt.Println(slices.Equal(numbers, []int{10})) // false
}
EqualFunc
func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool
EqualFunc
在每對元素上使用相等函數(shù)來報(bào)告兩個(gè)切片是否相等。如果長度不同,EqualFunc
返回false
。否則,按遞增索引順序比較元素,并且比較在eq
返回false
的第一個(gè)索引處停止。
示例:
package main
import (
"fmt"
"slices"
"strconv"
)
func main() {
numbers := []int{0, 42, 8}
strings := []string{"000", "42", "0o10"}
equal := slices.EqualFunc(numbers, strings, func(n int, s string) bool {
sn, err := strconv.ParseInt(s, 0, 64)
if err != nil {
return false
}
return n == int(sn)
})
fmt.Println(equal) // true
}
Grow
函數(shù)簽名如下:
func Grow[S ~[]E, E any](s S, n int) S
必要時(shí),Grow
會(huì)增加切片的容量,以保證另外n
個(gè)元素的空間。在Grow(n)
之后,至少可以將n
個(gè)元素附加到切片,而無需再次分配。如果n
為負(fù)數(shù)或太大而無法分配內(nèi)存,Grow 會(huì)出現(xiàn)panic
。
Index
函數(shù)簽名如下:
func Index[S ~[]E, E comparable](s S, v E) int
Index
返回v
在s
中第一次出現(xiàn)的索引,如果不存在則返回-1
。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, 8}
fmt.Println(slices.Index(numbers, 8)) // 2
fmt.Println(slices.Index(numbers, 7)) // -1
}
IndexFunc
函數(shù)簽名如下:
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int
Index
返回s
中第一次符合f(e)
的元素的索引,如果不存在則返回-1
。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, -10, 8}
i := slices.IndexFunc(numbers, func(n int) bool {
return n < 0
})
fmt.Println("First negative at index", i) // First negative at index 2
}
Insert
函數(shù)簽名如下:
func Insert[S ~[]E, E any](s S, i int, v ...E) S
Insert
將值v...
插入到索引i
處的s
中,返回修改后的切片。s[i:]
處的元素向上移動(dòng)以騰出空間。在返回的切片r
中,r[i] == v[0]
,并且r[i+len(v)] ==
最初位于r[i]
的值。如果i
超出范圍,則panic
。該函數(shù)的復(fù)雜度為O(len(s) + len(v))
。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
names = slices.Insert(names, 1, "Bill", "Billie")
names = slices.Insert(names, len(names), "Zac")
fmt.Println(names) // [Alice Bill Billie Bob Vera Zac]
}
IsSorted
函數(shù)簽名如下:
func IsSorted[S ~[]E, E cmp.Ordered](x S) bool
IsSorted
返回x
是否按升序排序。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
fmt.Println(slices.IsSorted([]string{"Alice", "Bob", "Vera"})) // true
fmt.Println(slices.IsSorted([]int{0, 2, 1})) // false
}
IsSortedFunc
函數(shù)簽名如下:
func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool
IsSortedFunc
返回x
是否按升序排序,使用cmp
作為比較函數(shù)。
示例:
package main
import (
"cmp"
"fmt"
"slices"
"strings"
)
func main() {
names := []string{"alice", "Bob", "VERA"}
isSortedInsensitive := slices.IsSortedFunc(names, func(a, b string) int {
return cmp.Compare(strings.ToLower(a), strings.ToLower(b))
})
fmt.Println(isSortedInsensitive) // true
fmt.Println(slices.IsSorted(names)) // false
}

聲明:本作品采用署名-非商業(yè)性使用-相同方式共享 4.0 國際 (CC BY-NC-SA 4.0)進(jìn)行許可,使用時(shí)請注明出處。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 戀水無意文章來源地址http://www.zghlxwxcb.cn/news/detail-710550.html
到了這里,關(guān)于slices in Go 1.21的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!