【问题标题】:Completely lost in trying to mutate property in sequence在尝试按顺序改变属性时完全迷失了
【发布时间】:2015-01-30 02:58:14
【问题描述】:

我完全不知道为什么这段代码不改变类型序列中的成员变量:

for p in prescrs do
    p.ATC <- "A"
    for c in p.Drug.Components do
        for s in c.Substances do
                s.DoseTotal.Adjust <- adjustKg
                s.DoseTotal.Time <- "DAY"
                s.DoseTotal.Unit <- s.DrugConcentration.Unit
                s.DoseRate.Adjust <- adjustKg
                s.DoseRate.Time <- "DAY"
                s.DoseRate.Unit <- s.DrugConcentration.Unit

prescrs 是一系列 Prescriptions,它是一个非常简单的“POCO”,定义为具有成员值的类型。我不知道为什么这不起作用。

我尝试了一个简单的测试用例,例如:

type IterTest () =
    member val Name = "" with get, set
    member val IterTests = [] |> List.toSeq : IterTest seq with get, set

let iterseq = 
    [
        new IterTest(Name = "Test1")
        new IterTest(Name = "Test2")
    ] 
    |> List.toSeq

iterseq |> Seq.iter(fun x -> x.IterTests <- iterseq)
iterseq |> Seq.iter(fun x -> 
    x.IterTests
    |> Seq.iter(fun x' -> x'.Name <- "itered"))

但是这里的结果与预期的一样。所以,甚至不能完全重现我的问题???

找到了解决方案(没有真正理解上面的问题)。当我第一次将 prescrs 序列转换为如下列表时:

let prescrs = prescrs |> Seq.toList

然后执行命令式循环,属性会发生变异。

【问题讨论】:

  • “这不起作用”是什么意思? prescrs是怎么产生的? (顺便说一句,let prescrs = prescrs |&gt; Seq.toList 是转换,而不是演员表。)
  • @ildjarn 我的意思是“不起作用”,属性没有改变。在第二个示例中,属性确实发生了变化。这两个示例都是对序列的迭代,所以我期望相同的行为。
  • 但是你怎么知道值没有改变呢?也许您的测试有缺陷... prescrs 是如何产生的? 当您没有为相关上下文显示足够的代码时,您希望如何获得帮助?
  • @ildjarn 看到下面的答案,我现在很高兴,感谢您对此进行调查。

标签: f# seq imperative


【解决方案1】:

试试这个示例:

type Mutable() = 
    member val Iterated = false with get, set

let muts = Seq.init 5 (fun _ -> printfn "init"; Mutable())

let muts2 = muts // try again with let muts2 = muts |> List.ofSeq

printfn "Before iter"

for a in muts2 do
    printfn "iter"    
    a.Iterated <- true 

printfn "After iter" 

muts2 |> List.ofSeq

并检查iterinit 是如何交错的。

Seqs 是惰性的,但一旦计算就不会被缓存。因此,即使您强制尝试改变 prescrs 序列中的某些元素,一旦您再次拉动 prescrs,这一切都会消失。如果您在进行突变之前将prescrs 更改为具体的集合类型(如列表),您将不再遇到同样的问题。请注意,如果您拥有的是 seq 内的 seq 内的 seq,事情可能会变得更加棘手。

不过,最好的办法是首先避免突变。

【讨论】:

  • 谢谢,解释得很好,明白了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多