联合测试表达式的类型测试产生错误
Type test yields error for union test-expression
我的问题与以下程序有关。
open System
// Types
type Car (brand: string) =
member _.Brand = brand
type BMW () =
inherit Car "BMW"
type Pet =
| Cat
| Dog
[<EntryPoint>]
let main argv =
// Match subtype of test-expression type: ok
let car = Car "Mercedes"
let carResult =
match car with
| :? BMW -> 1
| _ -> 0
// Match type of test-expression: "will always hold" warning
let bmw = BMW ()
let bmwResult =
match bmw with
| :? BMW -> 1
| _ -> 0
// Catch any exception: "will always hold" warning
let exceptionResult =
try
1/0
with
| :? Exception -> 2
// Match type of test-expression (union type): "The type 'Pet' does not have any proper subtypes" error
let cat = Cat // this has type Pet
let catResult =
match cat with
| :? Pet -> 1
| _ -> 0
0
第一次测试,test-expression的类型是Car
,类型测试模式中的类型BMW
是一个子类型,没有警告和错误.在第二个和第三个测试中,type test pattern 中的类型与 test-expression 的类型相同,并且会引发警告,这是可以理解的,因为当程序员在测试 BMW
是否真的是 a BMW
,或者 Exception
实际上是 Exception
,这很可能是逻辑错误。
最后一个测试与测试二和三的形式相同:测试表达式是Pet
类型,类型测试模式也是Pet
。那么为什么在这种情况下会产生错误呢?错误显示 The type 'Pet' does not have any proper subtypes...
。但是 BMW
没有任何子类型,也不会产生这个错误。此外,Pattern Matching 页面(在 "Type Test Pattern" 下)表示 "If the input type is a match to (or a derived type of) the type specified in the pattern, the match succeeds." Pet
与 Pet
、ergo 等相匹配。为什么要处理联合类型不同?
也许错误信息的措辞有点含糊。并不是类型 Pet
没有 子类型,而是它 不能 有子类型。
因为 BMW
是一个 class,它 可能 有一个来自不同程序集的子类型,它是在 [=12] 之后编译的=] 本身被定义。
但对于 Pet
这不可能发生,因为总和类型不能有子类型,因此禁止对这些类型进行继承匹配。
另请注意,错误来源是匹配的变量类型,而不是模式类型。因此,例如,这将编译没有错误:
let n : obj = null
match n with
| :? Pet -> "is a pet"
| _ -> "no idea"
这是有效的,因为 n
是类型 obj
, 有子类型,其中 Pet
是一个(这是.NET 毕竟,一切都是对象)。但是在您的变量 cat
上匹配不起作用,因为该变量本质上是无子类型的类型。
我的问题与以下程序有关。
open System
// Types
type Car (brand: string) =
member _.Brand = brand
type BMW () =
inherit Car "BMW"
type Pet =
| Cat
| Dog
[<EntryPoint>]
let main argv =
// Match subtype of test-expression type: ok
let car = Car "Mercedes"
let carResult =
match car with
| :? BMW -> 1
| _ -> 0
// Match type of test-expression: "will always hold" warning
let bmw = BMW ()
let bmwResult =
match bmw with
| :? BMW -> 1
| _ -> 0
// Catch any exception: "will always hold" warning
let exceptionResult =
try
1/0
with
| :? Exception -> 2
// Match type of test-expression (union type): "The type 'Pet' does not have any proper subtypes" error
let cat = Cat // this has type Pet
let catResult =
match cat with
| :? Pet -> 1
| _ -> 0
0
第一次测试,test-expression的类型是Car
,类型测试模式中的类型BMW
是一个子类型,没有警告和错误.在第二个和第三个测试中,type test pattern 中的类型与 test-expression 的类型相同,并且会引发警告,这是可以理解的,因为当程序员在测试 BMW
是否真的是 a BMW
,或者 Exception
实际上是 Exception
,这很可能是逻辑错误。
最后一个测试与测试二和三的形式相同:测试表达式是Pet
类型,类型测试模式也是Pet
。那么为什么在这种情况下会产生错误呢?错误显示 The type 'Pet' does not have any proper subtypes...
。但是 BMW
没有任何子类型,也不会产生这个错误。此外,Pattern Matching 页面(在 "Type Test Pattern" 下)表示 "If the input type is a match to (or a derived type of) the type specified in the pattern, the match succeeds." Pet
与 Pet
、ergo 等相匹配。为什么要处理联合类型不同?
也许错误信息的措辞有点含糊。并不是类型 Pet
没有 子类型,而是它 不能 有子类型。
因为 BMW
是一个 class,它 可能 有一个来自不同程序集的子类型,它是在 [=12] 之后编译的=] 本身被定义。
但对于 Pet
这不可能发生,因为总和类型不能有子类型,因此禁止对这些类型进行继承匹配。
另请注意,错误来源是匹配的变量类型,而不是模式类型。因此,例如,这将编译没有错误:
let n : obj = null
match n with
| :? Pet -> "is a pet"
| _ -> "no idea"
这是有效的,因为 n
是类型 obj
, 有子类型,其中 Pet
是一个(这是.NET 毕竟,一切都是对象)。但是在您的变量 cat
上匹配不起作用,因为该变量本质上是无子类型的类型。