gpt4 book ai didi

f# - f# : value has been copied to ensure the original is not mutated 产生的警告

转载 作者:行者123 更新时间:2023-12-03 22:44:30 26 4
gpt4 key购买 nike

当使用 f# 3.0 编译并且警告级别设置为 5 时,下面的第一个定义会在标题中产生警告。第二个定义编译干净。我想知道是否有人可以解释编译器担心我可能会意外变异的内容,或者使用 let 子句拆分表达式将如何帮助避免这种情况。非常感谢。

let ticks_with_warning () : int64 =
System.DateTime.Now.Ticks

let ticks_clean () : int64 =
let t = System.DateTime.Now
t.Ticks

最佳答案

我无法真正解释为什么编译器会在您的特定情况下发出此警告 - 我同意 @ildjarn 您可以放心地忽略它,因为编译器可能只是过于谨慎。

但是,我可以举一个例子,警告实际上可能会给您一个有用的提示,表明某些事情可能不会如您所愿。如果我们有一个可变的 struct像这样:

[<Struct>]
type Test =
val mutable ticks : int64
member x.Inc() = x.ticks <- x.ticks + 1L
new (init) = { ticks = init }

现在, Inc方法改变结构(你也可以访问可变字段 ticks )。我们可以尝试编写一个函数来创建 Test值并改变它:
let foo () =
let t = Test(1L)
t.Inc() // Warning: The value has been copied to ensure the original is not mutated
t

我们没有标注本地值 tmutable ,所以当我们调用 Inc 时,编译器会尝试确保该值没有发生变化。 .不知道是否 Inc改变值与否,所以唯一安全的方法是创建一个副本 - 因此 foo返回值 Test(1L) .

如果我们标记 tmutable ,然后编译器不必担心由于调用而对其进行变异,因此它不会发出警告(并且函数返回 Test(2L) ):
let foo () =
let mutable t = Test(1L)
t.Inc()
t

不过,我不确定是什么导致了您的示例中的警告。也许编译器认为(作为一些中间表示的结果) Ticks操作可能会改变左侧的值(分别为 System.DateTime.Nowt),并且它想防止这种情况发生。

奇怪的是,如果你自己写 DateTime struct 在 F# 中,除非您标记变量 t,否则在这两种情况下都会收到警告。如 mutable (这是我所期望的),但是标准的行为 DateTime是不同的。所以也许编译器知道一些我缺少的标准类型......

关于f# - f# : value has been copied to ensure the original is not mutated 产生的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13753312/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com