为什么切片a保持不变?是否append()产生一个新的片?
package main
import (
"fmt"
)
var a = make([]int, 7, 8)
func Test(slice []int) {
slice = append(slice, 100)
fmt.Println(slice)
}
func main() {
for i := 0; i < 7; i++ {
a[i] = i
}
Test(a)
fmt.Println(a)
}
Run Code Online (Sandbox Code Playgroud)
输出:
[0 1 2 3 4 5 6 100]
[0 1 2 3 4 5 6]
Run Code Online (Sandbox Code Playgroud) 我有以下功能:
func checkFiles(path string, excludedPatterns []string) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
我想知道,因为excludedPatterns永远不会改变,我应该通过使var全局(而不是每次都将它传递给函数)来优化它,或者Golang是否已经通过将它们作为copy-on-write传递来处理它?
编辑:我想我可以将切片作为指针传递,但我仍然想知道写时复制行为(如果它存在)以及一般来说我是否应该担心通过值或指针传递.
我按照示例https://tour.golang.org/moretypes/10 修改了代码,期望得到相同的结果.我没有.这是一个错误,还是文档错误?巡回演出
零片的长度和容量为0.
我的y变量的长度和容量为0.
package main
import "fmt"
func myPrint(z []int) {
fmt.Println(z, len(z), cap(z))
if z == nil {
fmt.Println("nil!")
}
}
func main() {
var z []int
y := []int {}
myPrint(z)
myPrint(y)
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出.
[] 0 0
nil!
[] 0 0
Run Code Online (Sandbox Code Playgroud)
我期待第二次"零"〜为什么我没有得到它?
我知道一切都是通过Go中的值传递的,这意味着如果我给一个函数提供了一个分片,并且该函数使用内置append函数附加到该分片上,则原始分片将不会具有附加在该函数范围内的值。
例如:
nums := []int{1, 2, 3}
func addToNumbs(nums []int) []int {
nums = append(nums, 4)
fmt.Println(nums) // []int{1, 2, 3, 4}
}
fmt.Println(nums) // []int{1, 2, 3}
Run Code Online (Sandbox Code Playgroud)
这给我带来了一个问题,因为我试图对累积的切片进行递归,基本上是一个reduce类型函数,除了reducer本身会调用它本身。
这是一个例子:
func Validate(obj Validatable) ([]ValidationMessage, error) {
messages := make([]ValidationMessage, 0)
if err := validate(obj, messages); err != nil {
return messages, err
}
return messages, nil
}
func validate(obj Validatable, accumulator []ValidationMessage) error {
// If something is true, recurse
if something {
if err := …Run Code Online (Sandbox Code Playgroud) 最近读了《Go编程语言书》,这是学习golang编程语言的好资源。\n6.2节中有一段关于类型的复制实例T在方法中是否是指针接收者时类型的复制实例,我无法理解。 \n有没有用一个有意义的例子来解释这一段?
\n\n6.2 使用指针接收器的方法
\n\n如果命名类型 T 的所有方法都有 T 本身的接收者类型(不是 *T ),则复制该类型的实例是安全的;调用它的任何方法都必然会生成一个副本。例如,time.Duration 值可以自由复制,包括作为函数的参数。但是,如果任何方法具有指针接收器,则应避免复制 T 的实例,因为这样做可能会违反内部不变量。例如,复制 bytes.Buffer 的实例将导致原始和副本为相同的底层字节数组别名( \xc2\xa72.3.2 )。后续的方法调用将产生不可预测的效果。
\n\n(Go 编程语言 Alan AA Donovan \xc2\xb7 Brian W. Kernighan)
\n
Go中的值语义和指针语义是什么意思?在本课程中,作者在解释数组和切片的内部时,曾经多次提及上述术语,我完全无法理解.
我的目标是使用 goroutines 和 channel,我想学习如何在不同的 goroutines 之间进行通信,我想避免死锁。我设法使用sync.WaitGroup,它工作得很好。
但是我收到一个错误说
1恐慌:同步:负WaitGroup计数器
goroutine 19 [正在运行]:
这个程序的目标很简单。
编码:
package main
import (
"fmt"
"sync"
"time"
)
type developer struct {
name string
setTimeForWebsite time.Time
}
type website struct {
owner string
created time.Time
}
var developers []developer
var websites []website
// A function to create a developer
func hireDeveloper(wg *sync.WaitGroup, workNumber int,
developerCreatedc chan developer, devs []developer) {
defer wg.Done() …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习 Go,但我无法弄清楚为什么递归调用堆栈末尾的这段代码返回一个空切片,有什么帮助吗?也tmp并不甚至似乎在调试器中注册。
func main() {
input := [3]int{4, 6, 7}
// expected [[6,7],[4,6,7],[4,6],[4,7]]
fmt.Println(findSubsequences(input))
}
func findSubsequences(nums [3]int) [][]int {
res := [][]int{}
list := []int{}
findSubsequence(res, list, nums, 0)
return res
}
func findSubsequence(res [][]int, list []int, nums [3]int, id int) [][]int {
if len(list) > 1 {
tmp := make([]int, len(list))
copy(tmp, list)
res = append(res, tmp)
}
var unique []int
for i := id; i < len(nums); i++ {
if id > 0 && nums[i] …Run Code Online (Sandbox Code Playgroud) 在大多数语言(如c ++)中,传递数组会导致通过引用隐式传递它,因此对函数中传递的数组进行的任何更改都将导致更改原始数组。我正在学习Golang,在Alan AA Donovan和Brian W. Kernighan撰写的“ Go编程语言”一书中,它的行为不同于其他语言-不会隐式地通过引用传递数组。
这让我有些困惑-这是否意味着在没有引用的情况下传递数组不应该修改数组本身?让我说明一下:
func main() {
tab := []int{1, 2, 3}
fmt.Println(tab)
// Results in [1 2 3]
reverse(tab)
fmt.Println(tab)
// Results in [3 2 1]
}
func reverse(tab []int) {
for i, j := 0, len(tab)-1; i < j; i, j = i+1, j-1 {
tab[i], tab[j] = tab[j], tab[i]
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,数组不是由引用传递的,但是反向函数会修改原始数组,因此它的工作方式有点像C ++程序那样。谁能解释我的区别?
PS:很抱歉,如果这是一个假的问题,我对Golang完全陌生,并且试图很好地理解基本知识。
func foo(arr []int) int和之间有什么区别func foo(arr [*num*]int) int?
这是两个例子:
func foo1(arr [2]int) int {
arr[0] = 1
return 0
}
func foo2(arr []int) int {
arr[0] = 1
return 0
}
func main() {
var arr1 = [2]int{3, 4}
var arr2 = []int{3, 4}
foo1(arr1)
println(arr1[0]) // result is 3, so arr in foo1(arr) is a copy
foo2(arr2)
println(arr2[0]) // result is 1, so arr in foo2(arr) is not a copy, it is a reference
}
Run Code Online (Sandbox Code Playgroud)
我还发现,如果我使用foo1(arr2) …