首页 > 解决方案 > F# 中的警告“此构造导致代码比类型注释指示的更通用”是什么意思

问题描述

我有生成此警告的代码。

有一些与 SO 相关的帖子,最接近的是这个:这种结构导致代码比类型注释所指示的更通用

但我看不到它适用于何处,因为我的代码已经在函数中

所以,有问题的代码非常简单:

let exists (key: 'a) =
    r.Exists(string key)

let set (key: 'a) value =
    r.Set((string key), value)

let get (key: 'a) =
    r.Get(string key)

let setDefault (key: 'a) value =
    if not (exists key) then
        set key value

我想要实现的是允许传递不同的枚举、字符串甚至整数作为键,并且,无论传递的类型是什么,它都会被转换为字符串(显然在合理范围内)

但是当我将该代码与枚举一起使用时,我会在标题中收到警告。

所以,我有两个问题:

标签: f#

解决方案


问题来自使用string. 如果您查看string 的源代码,您会看到它是inline,这意味着编译器需要在编译时确定类型。在您的情况下,这意味着必须先解析泛型类型,然后string才能调用,这反过来又迫使编译器选择可以工作的东西 - 在这种情况下,obj.

有两种简单的方法可以解决这个问题 - 首先,您可以使您的函数内联,这允许编译器将其推迟到使用您的字符串的函数被使用。这在许多情况下都有效,但如果他们做与您正在做的事情相同的事情,也可能会在稍后将其“推到”给您的 API 使用者。这看起来像:

let inline set (key: 'a) value =
    r.Set((string key), value)

另一种选择是避免使用string运算符,并使用 .NET 中的所有对象包含的事实ToString,并改为调用它:

let set (key: 'a) value =
    r.Set(key.ToString()), value)

任何一种方法都将避免警告并保持功能通用。


推荐阅读