如何解决Scala 中的装饰者模式
我在 Scala 中有以下代码。 我有几个关于功能和语法的问题。
type Logger = String => Unit
type Decorator = Logger => Logger
val uppercase: Decorator =
logger =>
(msg: String) => logger(msg.toupperCase)
val info: Decorator =
logger =>
(msg:String) => logger("info " + msg)
我是否理解正确,Decorator
是 ìnfo
函数的输入?
为什么这里不需要声明返回类型?
然后我使用这样的代码:
val prefixUppercase = info(uppercase(println(_)))
为什么我可以将 println(_)
传递给 uppercase
?
uppercase
函数需要 Decorator
类型的参数,而 println()
显然不是。
此外,我使用 println(_)
,但是当我尝试传递像 println(x)
这样的命名参数时,出现错误。
解决方法
我是否理解正确,Decorator
是 ìnfo
函数的输入?
val info: Decorator =
logger =>
(msg:String) => logger("info " + msg)
不,Decorator
是 info
的类型。
info
被声明为一个从 Logger
到 Logger
(Decorator
扩展为)的函数。
val info: Decorator = // info is a Decorator
// i.e. a function Logger => Logger
logger => // so this makes logger a Logger
// (the input for the Decorator)
// what follows is the output of the Decorator
// i.e. another Logger
// i.e. a function String => Unit
(msg:String) => // so this is that String input to the
// resulting (decorated) Logger
logger("info " + msg) // and this is what our decorator does
// to the String to be logged:
// we prefix it with "info "
// and give it to the underlying logger
为什么这里不需要声明返回类型?
正在声明返回类型(见上文)。
一般来说,Scala 非常擅长推断类型,因此如果 info
可以从其他已知类型派生,您实际上不需要声明它的类型,但是
a) 声明非显而易见的类型是一种很好的做法,尤其是在公共值上。这可以作为文档,加速编译并可以避免错误(如果推断的类型不是您想要的,它有助于追踪问题)
b) 在你的情况下,这也是让编译器知道 logger
应该有什么类型的最直接的方法。否则,您必须在其他地方声明。
为什么我可以将 println(_)
传递给 uppercase
?大写函数需要 Decorator
类型的参数,而 println()
显然不是。
uppercase
不需要 Decorator
,uppercase
is Decorator
,这意味着它是一个带有 {{1} } 并返回一个 Logger
。
所以它需要一个 Logger
,它是一个接受 Logger
并且不返回任何内容的函数。 String
就是这样一个函数,因此您可以将其传递给 println
(作为其 uppercase
输入参数)。
我尝试传递这样的命名参数 Logger
我收到一个错误。
在这种情况下,println(x)
是什么?
您需要创建一个 x
,意思是一个接受字符串且不返回任何特殊内容的函数。
Logger
可以。
x => println(x)
是同一件事的简写,并且会做。
println(_)
或 println(somethingElse)
不再是接受字符串的函数(它们不再接受任何参数),因此它们不是 println(123)
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。