有少數情況下,當F#記錄的行爲是奇怪的對我說:奇怪的行爲
上含糊不清不警告
type AnotherPerson = {Id: int; Name: string}
type Person = {Id: int; Name: string;}
// F# compiler will use second type without any complains or warnings
let p = {Id = 42; Name = "Foo";}
警告的記錄解構,而不是記錄的建設
F#編譯器在記錄「解構」時發出警告,而不是在前面的記錄構造中發出警告:
// Using Person and AnotherPerson types and "p" from the previous example!
// We'll get a warning here: "The field labels and expected type of this
// record expression or pattern do not uniquely determine a corresponding record type"
let {Id = id; Name = name} = p
注意,存在與模式匹配沒有警告(我懷疑那是因爲模式是使用「記載建築表現形式」,而不是與「記載解構式」建):
match p with
| {Id = _; Name = "Foo"} -> printfn "case 1"
| {Id = 42; Name = _} -> printfn "case 2"
| _ -> printfn "case 3"
類型缺少字段的推理錯誤
F#編譯器會選擇第二種類型,並且會因爲缺少Age字段而發出錯誤!
type AnotherPerson = {Id: int; Name: string}
type Person = {Id: int; Name: string; Age: int}
// Error: "No assignment given for field 'Age' of type 'Person'"
let p = {Id = 42; Name = "Foo";}
醜陋的語法「中記載解構」
我問了好幾家的同事我的一個問題:「這段代碼是怎麼一回事?」
type Person = {Id: int; Name: string;}
let p = {Id = 42; Name = "Foo";}
// What will happend here?
let {Id = id; Name = name} = p
這對每個人總有意外驚喜的是「ID」和「名」實際上是「左值」,雖然它們放置在表達的「右手邊」。我明白,這更多的是關於個人喜好,但是對於大多數人來說似乎很奇怪,在一個特定情況下,輸出值被放在表達的右側。
我不認爲所有這些都是錯誤,我懷疑這些東西大部分都是功能。
我的問題是:這種晦澀的行爲背後有沒有理性?
謝謝,@ pad。我瞭解目前採取最後定義的行爲是有據可查的。但對我而言,這似乎仍然很奇怪。在這種情況下,我更喜歡得到錯誤或警告。那麼我的部分稱爲「丟失字段的類型推斷錯誤」呢?你覺得合理嗎? –