Scala 类型定义和重写
我是Scala的新手,我项目的一部分以以下设计结束Scala 类型定义和重写,scala,Scala,我是Scala的新手,我项目的一部分以以下设计结束 trait StringService { def length(s: String): Int def vowels(s: String): Int } 这些方法被用作 def processStrings(operation: String => Int) = {...} 像processStrings(ss.length)这样的调用工作正常。现在我想抽象一下 这些方法的类型 type StringFuction = St
trait StringService {
def length(s: String): Int
def vowels(s: String): Int
}
这些方法被用作
def processStrings(operation: String => Int) = {...}
像processStrings(ss.length)
这样的调用工作正常。现在我想抽象一下
这些方法的类型
type StringFuction = String => Int
问题是像这样的实现
override def length(s: String): Int = { ... }
不再有效。当然,我可以和你一起去
override def length: StringFunction = { (s: String) => ... }
但这似乎有点不对劲。
正确的方法是什么?如果这不是真正的Scala方法,请随意建议不同的设计。好的,有不同的方法可以做到这一点,具体取决于您希望使用类型别名的目的。例如:
type StringFunction = String => Int
trait Foo { def foo(s: String) = ??? }
class Bar extends Foo {
def foo(s: String) = s.length
}
def foobar(f: StringFunction)(s) = f(s)
foobar(new Bar().foo)("bar")
这也有效:
type StringFunction = String => Int
trait Foo { def foo: StringFunction = ??? }
class Bar extends Foo {
override def foo = _.length
}
def foobar(f: StringFunction)(s) = f(s)
foobar(new Bar().foo)("bar")
严格地说,这些构造不同:在第一种情况下,Foo.Foo
是一个方法,它接受一个字符串参数并返回一个Int。
在第二种情况下,它是一个方法,不带参数,返回lambda函数,带字符串参数,返回Int
不过,这种差异相当微妙。在某些特定情况下,它确实很重要,但通常可以忽略。根据您使用类型别名的目的,有不同的方法可以做到这一点。例如:
type StringFunction = String => Int
trait Foo { def foo(s: String) = ??? }
class Bar extends Foo {
def foo(s: String) = s.length
}
def foobar(f: StringFunction)(s) = f(s)
foobar(new Bar().foo)("bar")
这也有效:
type StringFunction = String => Int
trait Foo { def foo: StringFunction = ??? }
class Bar extends Foo {
override def foo = _.length
}
def foobar(f: StringFunction)(s) = f(s)
foobar(new Bar().foo)("bar")
严格地说,这些构造不同:在第一种情况下,Foo.Foo
是一个方法,它接受一个字符串参数并返回一个Int。
在第二种情况下,它是一个方法,不带参数,返回lambda函数,带字符串参数,返回Int
不过,这种差异相当微妙。在某些特定情况下,它确实很重要,但通常可以忽略。您最初的实现仍然有效。你为什么不这么认为?你有错误吗?不知道你的意思。类似于
override-def-length(s:String)=s.length的实现会导致错误“方法长度不覆盖任何内容”。override-def-length:StringFunction=uu.length
工作正常,但我不喜欢它,原因是我不理解。尽管这是推荐的方法,我还是会接受的。没有完整的代码,不清楚什么是方法length
被覆盖的。我可以用完整的代码给出一个更好的答案。您最初的实现仍然有效。你为什么不这么认为?你有错误吗?不知道你的意思。类似于override-def-length(s:String)=s.length的实现会导致错误“方法长度不覆盖任何内容”。override-def-length:StringFunction=uu.length
工作正常,但我不喜欢它,原因是我不理解。尽管这是推荐的方法,我还是会接受的。没有完整的代码,不清楚什么是方法length
被覆盖的。我可以用完整的代码给出更好的答案。是的,Scala可以推断方法foo
属于StringFunction
类型。但是我想在trait中显式地使用类型。我怎样才能做到这一点?方法foo
实际上不是StringFunction
类型。函数和方法之间有一个微妙的区别,我在最后一段中试图解释。您可以将其定义为def foo:StringFunction=?
或val foo:StringFunction=???
来创建类型为StringFunction
的成员,如我的第二个代码片段所示。与其他方法相比,这可能对您没有什么好处。“因为我不明白的原因而不喜欢它”听起来并不是一个好的工程推理;)谢谢,迪玛。我理解这件事。我只是希望Scala有一个神奇的功能,可以在幕后将一个方法转换为lambda。在第一个示例中,调用foobar
需要神奇的eta扩展才能将foo
作为函数值传递。@deepdown这正是上面指出的情况。是的,Scala可以推断方法foo
属于StringFunction
类型。但是我想在trait中显式地使用类型。我怎样才能做到这一点?方法foo
实际上不是StringFunction
类型。函数和方法之间有一个微妙的区别,我在最后一段中试图解释。您可以将其定义为def foo:StringFunction=?
或val foo:StringFunction=???
来创建类型为StringFunction
的成员,如我的第二个代码片段所示。与其他方法相比,这可能对您没有什么好处。“因为我不明白的原因而不喜欢它”听起来并不是一个好的工程推理;)谢谢,迪玛。我理解这件事。我只是希望Scala有一个神奇的功能,可以在幕后将一个方法转换为lambda。在第一个示例中,调用foobar
需要神奇的eta扩展,才能将foo
作为函数值传递。@deepdown这正是上面所指出的情况。