我无法真正解释为什么编译器会在您的特定情况下发出此警告-我同意@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
我们没有将本地值标记t
为mutable
,因此编译器会尝试确保在我们调用 时该值不会发生变化Inc
。它不知道是否Inc
改变值,所以唯一安全的事情是创建一个副本 - 从而foo
返回值Test(1L)
。
如果我们标记t
为mutable
,那么编译器不必担心由于调用而改变它,因此它不会给出警告(并且函数返回Test(2L)
):
let foo () =
let mutable t = Test(1L)
t.Inc()
t
不过,我不确定是什么导致了您的示例中的警告。也许编译器认为(作为一些中间表示的结果)该Ticks
操作可能会改变左侧的值(System.DateTime.Now
和t
分别)并且它希望防止这种情况发生。
奇怪的是,如果您在 F# 中编写自己的DateTime
结构,则在这两种情况下都会收到警告,除非您将变量标记t
为mutable
(这是我所期望的),但标准的行为DateTime
是不同的。所以也许编译器知道我缺少的标准类型......