Scala中的类型安全字符串插值
受此启发,我想知道是否可以在Scala中使用类型安全的字符串插值(可能使用宏) 例如,我想要这样的东西Scala中的类型安全字符串插值,scala,type-safety,scala-macros,string-interpolation,scala-macro-paradise,Scala,Type Safety,Scala Macros,String Interpolation,Scala Macro Paradise,受此启发,我想知道是否可以在Scala中使用类型安全的字符串插值(可能使用宏) 例如,我想要这样的东西 def a[A] = ??? val greetFormat = f"Hi! My name is ${a[String]}. I am ${a[Int]} years old" greetFormat.format("Rick", 27) // compiles //greetFormat.format("Rick", false) // does not compile //gree
def a[A] = ???
val greetFormat = f"Hi! My name is ${a[String]}. I am ${a[Int]} years old"
greetFormat.format("Rick", 27) // compiles
//greetFormat.format("Rick", false) // does not compile
//greetFormat.format(27, "Rick") // does not compile
//greetFormat.format("Rick", 27, false) // does not compile
//greetFormat.format("Rick") // does not compile or is curried?
把它包装成一个函数
def greet(name: String, age: Int) = s"Hi! My name is $name. I am $age years old"
把它包装成一个函数
def greet(name: String, age: Int) = s"Hi! My name is $name. I am $age years old"
f
字符串插值器已使用宏实现
这可以在REPL中演示:
scala> val b = "not a number"
b: String = not a number
scala> f"$b%02d"
<console>:9: error: type mismatch;
found : String
required: Int
f"$b%02d"
^
scala>val b=“不是数字”
字符串=不是一个数字
scala>f“$b%02d”
:9:错误:类型不匹配;
找到:字符串
必填项:Int
f“$b%02d”
^
字符串插值器已通过宏实现
这可以在REPL中演示:
scala> val b = "not a number"
b: String = not a number
scala> f"$b%02d"
<console>:9: error: type mismatch;
found : String
required: Int
f"$b%02d"
^
scala>val b=“不是数字”
字符串=不是一个数字
scala>f“$b%02d”
:9:错误:类型不匹配;
找到:字符串
必填项:Int
f“$b%02d”
^
您可以向f插值器提供隐式:
scala> case class A(i: Int)
defined class A
scala> implicit def atoi(a: A): Int = a.i
warning: there were 1 feature warning(s); re-run with -feature for details
atoi: (a: A)Int
scala> f"${A(42)}%02d"
res5: String = 42
有关详细信息,请参见和解决方案。我花了大约一分钟才想出那个好主意
"a123bc" match {
case res @ xr"(?<c>a)(?<n>\d+)(?<s>bc)" => assert {
res.c == 'a' && res.n == 123 && res.s == "bc"
}
}
但人们认为这对穷人来说太过分了。你必须像另一个答案那样写函数
在窗体中,宏可以看到“${a[Int]}”
并使用Int
参数编写函数,实现起来并不困难
f插值器的其他功能包括其他静态错误检查:
scala> f"$b%.02d"
<console>:19: error: precision not allowed
f"$b%.02d"
^
快速宏可能会发出
(i:Int)=>f“${new Formattable{…}}”
您可以向f-interpolator提供隐式:
scala> case class A(i: Int)
defined class A
scala> implicit def atoi(a: A): Int = a.i
warning: there were 1 feature warning(s); re-run with -feature for details
atoi: (a: A)Int
scala> f"${A(42)}%02d"
res5: String = 42
有关详细信息,请参见和解决方案。我花了大约一分钟才想出那个好主意
"a123bc" match {
case res @ xr"(?<c>a)(?<n>\d+)(?<s>bc)" => assert {
res.c == 'a' && res.n == 123 && res.s == "bc"
}
}
但人们认为这对穷人来说太过分了。你必须像另一个答案那样写函数
在窗体中,宏可以看到“${a[Int]}”
并使用Int
参数编写函数,实现起来并不困难
f插值器的其他功能包括其他静态错误检查:
scala> f"$b%.02d"
<console>:19: error: precision not allowed
f"$b%.02d"
^
快速宏可能会发出
(i:Int)=>f“${new Formattable{…}}”
在大多数情况下可能是更好的设计,但不会回答OPs关于如何以通用方式执行的问题在大多数情况下可能是更好的设计,但不会回答OPs关于如何以通用方式执行的问题。但是,它迫使我为它提供格式化程序,以触发类型检查失败,例如,如果我只是执行f“$b”
,并且b
是Int
它仍然可以工作。我想要像f“${a[String]}”
@wrick这样的东西,它实际上与类型安全的字符串插值无关-您想要确保变量符合字符串插值甚至不需要的类型。在任何情况下,使用f“${a:String}”
f“$b”
都可以轻松完成您想要的操作,我明白了,这只是f“$b%s”的缩写。但是,它迫使我为它提供格式化程序,以触发类型检查失败,例如,如果我只是执行f“$b”
,并且b
是Int
它仍然可以工作。我想要像f“${a[String]}”
@wrick这样的东西,它实际上与类型安全的字符串插值无关-您想要确保变量符合字符串插值甚至不需要的类型。在任何情况下,使用f“${a:String}”
f“$b”
都可以轻松完成所需的操作,它只是f“$b%s”