3

What is the best way to write a pure function in go if I need to pass a (small) slice in parameter? Slice are not passed by value like array. So it's not possible to guarantee that it will not be modified during the execution of the function. Once solution is to copy the slice every time I call the function. It would work in practice, but I would prefer a more safe solution as there is no way to ensure that a copy will ever be made before the function call.

4

3 回答 3

2

你是对的,因为切片是参考值,所以不可能有一个真正纯的带有切片参数的函数。

根据您的需要,您可以使用数组。数组具有固定数量的元素,声明如下:

var myArray [10]int

数组在按值传递时被复制。

另一种可能性是将切片封装在一个接口中,该接口只允许从切片中读取,而不是对其进行写入。

这是一个例子

package main

import "fmt"

// The interface
type ReadOnlyStringSlice interface {
    Get(int) string
}

// An implementation of ReadOnlyStringSlice
type MyReadOnlySlice struct {
    slice []string
}

func (m MyReadOnlySlice) Get(i int) string {
    e := m.slice[i]
    return e
}

// Your "pure" function
func MyPureFunction(r ReadOnlyStringSlice) {
    fmt.Println(r.Get(0))
}

func main() {
    m := MyReadOnlySlice{[]string{"foo", "bar"}}
    MyPureFunction(m)
}
于 2012-12-10T21:52:48.237 回答
2

不是一个真正的答案,但我想仍然值得讨论。

我认为整个想法是一厢情愿的想法:在一种语言中努力拥有一个纯函数是没有意义的,它不会以任何方式使用你的函数是纯函数的事实。如果你可以将一个函数“标记”为纯函数,那么理论上 Go 将能够以某种方式利用这个提示来发挥它的优势(例如,在一系列调用中重新排序某些函数的执行)。由于没有明确支持此类事情,因此函数的纯度只存在于您的脑海中。例如,假设您能够以某种方式强制函数不修改传递给它的切片;即使这样,也没有什么可以阻止您在该函数中执行另一个副作用(例如,执行 I/O 或修改全局变量)。

如果您正在编写一个库并希望其调用者提供一个回调,该回调获取一个回调不得更改的切片,只需在文档中清楚地说明这一事实。

于 2012-12-16T22:21:24.103 回答
0

If you're writing a package, you could export a method which takes a slice but copies it and passes it to the real function:

func MyExportedFunc(someSlice []int) {
    sliceCopy := make([]int, len(someSlice))
    copy(sliceCopy, someSlice)

    myUnexportedFunc(sliceCopy)
}

This, of course, is not a solution for the problem in general, as MyExportedFunc is not pure. The best way is probably to encapsulate the slice, as @Tom suggested.

于 2012-12-11T00:21:26.250 回答