相关疑难解决方法(0)

golang切片是否超值?

在Golang,我正在尝试为我的旅行推销员问题制作一个争夺切片功能.虽然这样做我注意到当我开始编辑切片时,我给每个传递它时的加扰功能是不同的.

经过一些调试后我发现它是由于我编辑了函数内部的切片.但由于Golang应该是一种"通过价值传递"的语言,这怎么可能呢?

https://play.golang.org/p/mMivoH0TuV

我提供了一个游乐场链接来展示我的意思.通过删除第27行,您获得的输出与输入不同,这应该没有区别,因为该函数在作为参数传入时应该创建自己的切片副本.
有人可以解释这种现象吗?

pass-by-value go slice

32
推荐指数
4
解决办法
2万
查看次数

当命名类型 T 的任何方法具有指针接收器时,复制类型 T 的实例

最近读了《Go编程语言书》,这是学习golang编程语言的好资源。\n6.2节中有一段关于类型的复制实例T在方法中是否是指针接收者时类型的复制实例,我无法理解。 \n有没有用一个有意义的例子来解释这一段?

\n\n
\n

6.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
\n

methods pointers go

4
推荐指数
1
解决办法
648
查看次数

Go中的"值语义"和"指针语义"是什么意思?

Go中的值语义指针语义是什么意思?在本课程中,作者在解释数组和切片的内部时,曾经多次提及上述术语,我完全无法理解.

pass-by-value go data-structures pass-by-pointer

4
推荐指数
1
解决办法
569
查看次数

要在参数中使用的切片与映射

在golang中,切片和贴图都是引用类型.当您只需要修改切片/贴图中的元素时,切片/贴图成员的修改将"广播"到所有切片.例如,给定m1 := make(map[int]int); m2 := m1,m1[3] = 5将导致m2[3] == 5.

但是,当您尝试将新元素添加到这两种类型时,事情开始有所不同.如下例所示,添加到地图参数中的新元素将自动显示在参数中; 但是,添加到切片中的新元素在参数中被"丢弃".

问题是,为什么这有区别?

func editMap(m map[int]int) {
    m[3] = 8
    m[4] = 9
}

func editSlice(s []int) {
    s = append(s, 5)
    s = append(s, 9)
}

func main() {
    m := make(map[int]int, 0)
    m[1] = 5
    m[2] = 3
    fmt.Printf("%v\n", m)  //map[1:5 2:3]
    editMap(m)
    fmt.Printf("%v\n", m)  //map[1:5 2:3 3:8 4:9]

    s := make([]int, 2)
    s[0] = 2
    s[1] = 5
    fmt.Printf("%v\n", s)  //[2 …
Run Code Online (Sandbox Code Playgroud)

dictionary reference go slice

2
推荐指数
1
解决办法
657
查看次数

使用值接收器附加到具有足够容量的切片

有人可以帮助我理解这里发生了什么吗?

package main

import (
    "fmt"
)

func appendString(slice []string, newString string) {
    slice = append(slice, newString)
}

func main() {
    slice := make([]string, 0, 1)
    appendString(slice, "a")
    fmt.Println(slice)
}
Run Code Online (Sandbox Code Playgroud)

我了解切片头以及使用指针接收器的需要。但在这里,由于底层数组有足够的容量,我希望追加能够正常工作(只需将新值添加到底层数组中,原始的[复制]标头按预期工作)

我的假设有什么问题吗?

pointers append go slice

1
推荐指数
1
解决办法
60
查看次数

Golang 读取 csv 消耗的内存空间是磁盘空间的 2 倍以上

我正在使用 Golang 将大量 CSV 文件加载到结构中。结构是

type csvData struct {
    Index   []time.Time
    Columns map[string][]float64
}    
Run Code Online (Sandbox Code Playgroud)

我有一个解析器使用:

csv.NewReader(file).ReadAll()
Run Code Online (Sandbox Code Playgroud)

然后我迭代行,并将值转换为其类型:time.Timefloat64

问题是这些文件在磁盘上占用了 5GB 空间。一旦我将它们加载到内存中,它们就会消耗 12GB!

我使用ioutil.ReadFile(path)后发现,正如预期的那样,这几乎与磁盘上的大小完全相同。

这是我的解析器的代码,为了可读性省略了错误,如果您可以帮助我排除故障:

csv.NewReader(file).ReadAll()
Run Code Online (Sandbox Code Playgroud)

我尝试通过在函数调用结束时将columnData和设置为 nil 来进行故障排除,但没有任何变化。reader

csv go

1
推荐指数
1
解决办法
1492
查看次数

解决 Go 的地图指针问题

我正在解决这个 Project Euler 问题。首先我尝试了暴力破解,花了 0.5 秒,然后我尝试了动态编程来利用记忆化,期望有巨大的改进,但令我惊讶的是结果是 0.36 秒。

经过一番谷歌搜索后,我发现您不能在函数(find_collat​​z_len)中使用指向外部地图数据(备忘录)的指针。因此,每次运行下面的函数时,它都会复制整个字典。这听起来像是对处理器能力的巨大浪费。

我的问题是有什么解决方法,以便我可以使用指向函数外部映射的指针来避免复制。

这是我的丑陋代码:

package main
//project euler 014 - longest collatz sequence

import (
    "fmt"
    "time"
)

func find_collatz_len(n int, memo map[int]int) int {
    counter := 1
    initital_value := n
    for n != 1 {
        counter++
        if n < initital_value {
            counter = counter + memo[n]
            break
        }
        if n%2 == 0 {
            n = int(float64(n)/2)
        } else {
            n = n*3+1
        }
    }
    memo[initital_value] = counter
    return counter
} …
Run Code Online (Sandbox Code Playgroud)

algorithm dictionary go

0
推荐指数
1
解决办法
249
查看次数