Scala 中的条件隐式函数
Conditional Implicit functions in Scala
我正在尝试用 Scala 设计 DSL。为此,我想在精确的字符串上创建一个隐式函数。
我知道要为任何字符串创建一个隐式函数,我可以这样写:
class StringPlus(str: String) {
def some_function(): Unit = do_something
}
implicit def string2StringPlus(str: String) = new StringPlus(str)
但我不知道如何修改它来为某些字符串创建这个隐式函数。是否可以为隐式函数提供一个布尔条件,以便仅当布尔条件为真时才创建隐式函数(例如,如果字符串的长度为 5 或更多,如果字符串的第一个字母是字母 "a" 等)而不是所有字符串 ?
简答
不,这不可能。
类型和隐式在编译时解析,而您的 String 的实际值是运行时实体,即它可能在运行之间不同。所以在编译时不可能知道哪个字符串值将被传递给隐式函数。
长答案
这可能是可行的,但包含大量的类型魔术,就可读性和实用性而言,这绝对不是一个好的解决方案。
思路如下:您可以为字符串创建自定义类型并在该类型中编码必要的条件。例如,AString[String[...]]
表示以 "a" 开头的字符串,String[String[String[StringNil]]]
表示 3 个字母的字符串,依此类推。
然后所有字符串转换都会产生适当的类型,例如,当您在 String[...]
前面加上字母 A
时,您将得到 AString[String[...]]
,等等。
看看dependent types and the implementation of HList。
但同样,这在您的情况下并不实用。
UPD:另请查看 Refined 项目,它提供了类型级别的谓词。
我正在尝试用 Scala 设计 DSL。为此,我想在精确的字符串上创建一个隐式函数。 我知道要为任何字符串创建一个隐式函数,我可以这样写:
class StringPlus(str: String) {
def some_function(): Unit = do_something
}
implicit def string2StringPlus(str: String) = new StringPlus(str)
但我不知道如何修改它来为某些字符串创建这个隐式函数。是否可以为隐式函数提供一个布尔条件,以便仅当布尔条件为真时才创建隐式函数(例如,如果字符串的长度为 5 或更多,如果字符串的第一个字母是字母 "a" 等)而不是所有字符串 ?
简答
不,这不可能。
类型和隐式在编译时解析,而您的 String 的实际值是运行时实体,即它可能在运行之间不同。所以在编译时不可能知道哪个字符串值将被传递给隐式函数。
长答案
这可能是可行的,但包含大量的类型魔术,就可读性和实用性而言,这绝对不是一个好的解决方案。
思路如下:您可以为字符串创建自定义类型并在该类型中编码必要的条件。例如,AString[String[...]]
表示以 "a" 开头的字符串,String[String[String[StringNil]]]
表示 3 个字母的字符串,依此类推。
然后所有字符串转换都会产生适当的类型,例如,当您在 String[...]
前面加上字母 A
时,您将得到 AString[String[...]]
,等等。
看看dependent types and the implementation of HList。
但同样,这在您的情况下并不实用。
UPD:另请查看 Refined 项目,它提供了类型级别的谓词。