y类型的东西很奇怪,我不明白这是否合理。我倾向于不这么认为。
此代码可以正常工作:
type DictionarySingleton private () =
static let mutable instance = Dictionary<string*obj, obj>()
static member Instance = instance
let memoize (f:'a -> 'b) =
fun (x:'a) ->
let key = f.ToString(), (x :> obj)
if (DictionarySingleton.Instance).ContainsKey(key)
then let r = (DictionarySingleton.Instance).[key]
r :?> 'b
else
let res = f x
(DictionarySingleton.Instance).[key] <- (res :> obj)
res
这些人抱怨
type DictionarySingleton private () =
static let mutable instance = Dictionary<string*obj, _>()
static member Instance = instance
let memoize (f:'a -> 'b) =
fun (x:'a) ->
let key = f.ToString(), (x :> obj)
if (DictionarySingleton.Instance).ContainsKey(key)
then let r = (DictionarySingleton.Instance).[key]
r :?> 'b
else
let res = f x
(DictionarySingleton.Instance).[key] <- (res :> obj)
res
差异只是字典定义中的下划线。 推理类型相同,但从r到类型'b的动态转换表现出错误。
'此运行时强制...某些类型等不允许运行时类型测试。'
我错过了什么或者是粗糙的边缘?
答案 0 :(得分:1)
如果您分两步编译,首先输入DictionarySingleton
,然后输入功能memoize
。
看起来编译器首先尝试计算下划线的类型(可能是泛型类型),在决定它的obj
之前,它也会尝试推断r的类型。因此,在那时它仍然没有与obj
统一,这就是为什么如果你一次编译就会失败的原因。