我无法真正解释为什么编译器会在您的特定情况下发出此警告-我同意@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是不同的。所以也许编译器知道我缺少的标准类型......