我在考虑是否有可能创建一种将字符串作为参数的数据结构,并且该字符串不包含.txt或类似的东西,这会给我带来编译错误吗?
我可以针对我的问题进行具体说明-我试图将文件作为函数的参数(源),但被告知当前我正在传递任何类型的文件,并且只应采用文本文件,因此没有正确完成。我该如何处理? -谢谢!! ^^
答案 0 :(得分:4)
是的,这不是问题。最大的问题是您是否应该这样做。如果您的代码是各种各样的库,那么在某些情况下这可能是有道理的。从http4s项目中检出Uri.uri
在您的情况下,实现可能如下所示:
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
class Macros(val c: Context) {
import c.universe._
def txtFile(fileName: c.Expr[String]): Tree =
fileName.tree match {
case Literal(Constant(s: String)) if s.endsWith(".txt") =>
fileName.tree
case _ =>
c.abort(
c.enclosingPosition,
s"Supplied parameter is not a text file"
)
}
}
object MyObject {
def txtFile(fileName: String): String = macro Macros.txtFile
}
您可以这样使用:
val x: String = txtFile("abc.tx") // Fails to compile
val y: String = txtFile("abc.txt") // Compiles
同样可以做到,但是您可能想使用Option
:-)
答案 1 :(得分:3)
假设String来自代码库之外的其他地方(Web请求,cmd行),则需要将该String传递给接受String的对象。这样,您就可以将String转换为特殊的文件名数据类型。因此,我看不出有什么方法可以防止某种运行时检查。
如果要进行运行时检查以避免错误,则可以返回Option
,如果String不是有效的文件名,则返回None
答案 2 :(得分:1)
您可以使用refined库:
type TxtSuffix = EndsWith[W.`".txt"`.T]
type TxtFile = String Refined TxtSuffix
要构造TxtFile
,您需要给它一个以“ .txt”结尾的字符串:
val file: TxtFile = refineMV[TxtSuffix]("some.pdf") // compiler error
error: Predicate failed: "some.pdf".endsWith(".txt")