如何訪問受歧視的會員的指定字段?訪問DU會員的姓名字段
例子:
type Point = | Point of x : int * y : int
let p = Point(3, 1)
// how to access x-value or y-value of p here?
如何訪問受歧視的會員的指定字段?訪問DU會員的姓名字段
例子:
type Point = | Point of x : int * y : int
let p = Point(3, 1)
// how to access x-value or y-value of p here?
在一般情況下,工會與名爲下地幹活就像任何其他的聯盟類型:您將通過match
訪問字段:
let x, y =
match p with
| Point (x1, y1) -> x1, y1
The F# documentation還提到匹配的一種方式只有一些命名參數。在你的情況下,這意味着你可以寫:
let xOnly =
match p with
| Point (x = x1) -> x1
如果你只有一個案例,請參閱@ p.s.w.g的答案。該答案中的代碼對所有受歧視的工會都是通用的。對於命名字段單身工會,你可以使用上面所示的特殊語法,寫:
let Point(x = myX) = p
這種結合現場x
到myX
值。
PS根據意見:爲什麼你不能通過做p.x
讀出字段?您可以將受歧視的聯盟想象爲一個小對象層次結構(並使用它,請參閱discriminated union documentation:「您可以經常使用區分聯合作爲較小對象層次結構的簡單替代方法」)。考慮以下DU:
type Shape = | Circle of r: float | Square of float
您可以查看Shape
作爲超類。 Circle
和Square
是兩個派生類,每個類都有一個float
屬性。您創建的Circle
或Square
的每個實例都將被upcast爲Shape
。
因此,它變得很清楚爲什麼你不能立即讀出這些字段:你首先需要確定你正在查看哪些派生類,只有在轉換到正確的子類後,才能讀出字段。
這個對象層次視圖非常緊密地匹配如何下游用戶由F#內部處理:如果你看一下在反射杜類型,你會看到兩個嵌套類型具有相同的名稱作爲您的工會情況:
> typeof<Shape>.GetNestedTypes()
|> Seq.iter (fun t ->
let p = t.GetProperties()
let s =
p
|> Array.map (fun p -> sprintf "%s: %s" p.Name p.PropertyType.Name)
|> String.concat "; "
printfn "Nested type %s: %i Properties %s" t.Name p.Length s
);;
Nested type Tags: 0 Properties
Nested type Circle: 4 Properties r: Double; Tag: Int32; IsCircle: Boolean; IsSquare: Boolean
Nested type Square: 4 Properties Item: Double; Tag: Int32; IsCircle: Boolean; IsSquare: Boolean
實際數據存在於子類的屬性中。對於Circle
,我們使用了命名字段,您會看到屬性r
。對於Square
,我們有Item
屬性中的數據(如果有多個參數,則爲Item1
,Item2
)。其餘的是編譯器生成的:數字Tag
字段,將用於快速區分子類和子類檢查的兩個bool屬性。
超類本身只有編譯器生成的屬性:
> typeof<Shape>.GetProperties()
|> Seq.iter (fun p -> printfn "Property %s" p.Name);;
Property Tag
Property IsCircle
Property IsSquare
對單的情況下識別聯合喜歡你的榜樣,你不需要使用match-with
表達。你可能只是這樣做:
let (Point (x, y)) = p
printf "%i" x // 3
或者只得到x
而忽略y
:
let (Point (x, _)) = p
printf "%i" x // 3
是不存在實現像任何短語法'讓P2 =點(PX,PY)' ? –
在一般情況下,有多個工會案例:沒有。 'p'可以是一個表示'Point'情況的對象,也可以是其他一些工會情況。如果你想用OOP的術語來思考它:'p'是超類的一個實例,但是你試圖訪問派生類的字段。 'match'與cast相當,並且可以訪問這些字段。 –
@no_mindset,如果您只有一個案例,並且您對較短的語法感興趣,請使用記錄,而不是聯合。 –