Go 以切片作为参数的纯函数

Go 以切片作为参数的纯函数,go,Go,如果需要传入一个(小的)切片参数,那么编写in-go的最佳方法是什么? 切片不会像数组一样通过值传递。因此,无法保证在函数执行期间不会对其进行修改。 唯一的解决方案是每次调用函数时复制切片。这在实践中是可行的,但我更喜欢一个更安全的解决方案,因为没有办法确保在函数调用之前进行复制。您是对的,因为切片是引用值,所以不可能使用带有切片参数的真正纯函数 根据需要,可以使用阵列。数组具有固定数量的元素,声明如下: var myArray [10]int 数组在按值传递时被复制 另一种可能是将切片封装在

如果需要传入一个(小的)切片参数,那么编写in-go的最佳方法是什么? 切片不会像数组一样通过值传递。因此,无法保证在函数执行期间不会对其进行修改。
唯一的解决方案是每次调用函数时复制切片。这在实践中是可行的,但我更喜欢一个更安全的解决方案,因为没有办法确保在函数调用之前进行复制。

您是对的,因为切片是引用值,所以不可能使用带有切片参数的真正纯函数

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

var myArray [10]int
数组在按值传递时被复制

另一种可能是将切片封装在一个接口中,该接口只允许读取切片,而不允许写入切片

:


如果您正在编写一个包,您可以导出一个方法,该方法获取一个切片,但复制 并将其传递给实函数:

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

    myUnexportedFunc(sliceCopy)
}
当然,这通常不是问题的解决方案,因为
MyExportedFunc
不是
纯净的最好的方法可能是像@Tom建议的那样封装切片。

这不是一个真正的答案,但我认为仍然值得讨论

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


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

如何在一个本质上是引用的类型上有一个“pure”函数?在中,您必须传递实际数组。
func MyExportedFunc(someSlice []int) {
    sliceCopy := make([]int, len(someSlice))
    copy(sliceCopy, someSlice)

    myUnexportedFunc(sliceCopy)
}