我想要创建一个Person实例。人是一种动物。当我尝试创建一个Person时,IDE对我说:“这个表达式预计会有'Person'类型,但是这里有'Animal'类型。使用同名联盟类型创建新对象
type Person(name) =
member this.Name: string = name
type Animal =
| Person of Person
| Cat
| Dog
let person: Person = Person(name = "John")
我想要创建一个Person实例。人是一种动物。当我尝试创建一个Person时,IDE对我说:“这个表达式预计会有'Person'类型,但是这里有'Animal'类型。使用同名联盟类型创建新对象
type Person(name) =
member this.Name: string = name
type Animal =
| Person of Person
| Cat
| Dog
let person: Person = Person(name = "John")
问题是Person
引用了歧视联盟的类型和大小写。
可以反转的定义,因此将解决最后一个:
type Animal =
| Person of Person
| Cat
| Dog
and
Person (name) =
member this.Name: string = name
let person: Person = Person(name = "John")
// then to create an animal
let animal = Animal.Person (Person(name = "John"))
替代解决方案是使用new
关键词作为@MarcinJuraszek建议的意见或考虑杜情况和不同的名称类型。
“类型,例外或模块'Person'的重复定义”。 –
在这种情况下,你会如何创建一个'Animal'类型的人? – Matiasd
@Matiasd我只发布IDE所说的错误。联合人员没有参数,但Person类是。 –
在F#中,名称可以作为类型和值的绑定,并且您可以随时重新定义名称“指向”的名称。例如。
// lets define type A
type A(name) = member this.Name : string = name
let x = A("test")
// lets "bind" the type name 'A' to a new type
type A(number) = member this.Number : int = number
let y = A(10)
printfn "type name of x: %s" (x.GetType().Name) // prints 'type name of x: A'
printfn "type name of y: %s" (y.GetType().Name) // prints 'type name of y: A'
所以x
和y
都是一个名为A
型的,但不一样的。同样的逻辑适用于Person
和Animal.Person
,并且取决于您定义它们的顺序,最后定义的将是在键入Person
时引用的那个。
如上所述,您可以使用新的或定义顺序来访问两者。您也可以决定将Person
类放在与Animal
不同的模块中。
module Inner =
type Person(name) ...
这样,您可以通过预先输入模块名称来访问您的类型。
我不知道为什么它是这样的,所以我不会将它作为答案添加它,但是如果您添加'new',它将起作用:'let person:Person = new Person(name =“John”)''。 – MarcinJuraszek
@MarcinJuraszek我不想使用'new'关键字,如果我使用'new',IDE说我'新'是多余的。 –
有趣。我只在F#Interactive中测试过它。 – MarcinJuraszek