以下脚本改变了不可变变量 jar,没有错误或警告。这是一个错误吗?还是我的理解有问题?
请解释为什么我不需要使用 mutable 关键字。
旁白:FSharp.Data.Http.RequestString 的 cookieContainer 参数在定义中未标记为可变:https://github.com/fsprojects/FSharp.Data/blob/134a08cda3acb8e746bb25d03692d90ee5caabab/src/Net/Http.fs
#r "System.Xml.Linq.dll";;
#r "nuget:FSharp.Data";;
open FSharp.Data
let url="http://www.google.com"
let uri=System.Uri(url)
// no mutable keyword here
let jar=System.Net.CookieContainer()
// Count is 0
printf $"Pre-request cookie count is: {jar.GetCookies(uri).Count}\n"
let r = Http.RequestString(url, cookieContainer=jar)
// Count is 1
printf $"Post-request cookie count is: {jar.GetCookies(uri).Count}\n"
Run Code Online (Sandbox Code Playgroud)
#r "System.Xml.Linq.dll";; #r "nuget:FSharp.Data";;
Tom*_*cek 10
F# 中有两个与变异相关的不同概念:
可变变量,是可以改变值的变量。它们是使用定义的let mutable,并且可以使用更改值<-(如果变量不可变,则这是不可能的)。
可变对象只是具有某些可变状态的 .NET 对象,可以通过调用对象上的方法来更改这些可变状态。这些是普通 C# 样式类的实例。
如果定义一个不可变变量是对可变对象的引用,则该对象仍然可以发生变化。变量不可变这一事实并不能阻止这种情况的发生。这就是你的情况。
就像不可变变量一样,也存在不可变对象(或值)。这包括 F# 数据类型,例如记录和可区分联合。然而,语言中不会跟踪对象是否可变这一事实 - 因此您不会以任何明显的方式看到这一点。
在精心设计的 F# 代码中,您自己的大多数对象将是不可变的,但您正在使用的大多数 .NET 对象(用于访问 .NET 提供的功能)将是可变的 - 因为这就是 .NET 的设计方式。