scala的新手并试图获得类系统的挂起。这是一个简单的设置:
sealed trait Shape{
def sides:Int
}
final case class Square() extends Shape {
def sides() = 4
}
final case class Triangle() extends Shape {
def sides() = 3
}
现在,我想创建一个函数,它接收shape
类型的任何类型,我们知道它将实现sides()
方法,并使用该方法。
def someFunction(a: Shape)={
val aShape = a()
aShape.sides()
}
但这会在val aShape = a()
遇到错误,因为没有类型a
。
我意识到在这个例子中,创建someFunction
是过分的,因为可以直接从对象访问sides()
。但我的主要问题是在someFunction
的上下文中 - 我想将一个类传递给一个函数,并实例化该类的一个对象,然后对该对象做一些事情。谢谢你的帮助。
答案 0 :(得分:1)
你想用这行代码做什么?您已经拥有shape
,传入的名为a
。只需删除该行,然后拨打a.sides()
。
在风格上,有几个问题。首先,类名应以大写字母开头。其次,sides
似乎是一个不可变的属性,而不是一个变异的方法,所以它应该被声明和覆盖而没有括号。您的子类中还需要override
个修饰符。最后,你可以不用空括号:{4}
应该是4
。
答案 1 :(得分:1)
有几种方法可以做到这一点。一个是复杂的使用reflection,第二个是稍微简单一点,使用builder,第三个是最直接的用例。
只需将someFunction
的定义更改为
def someFunction(a: ()=>Shape)={
val aShape = a()
aShape.sides
}
所以someFunction(Square)
返回4
,someFunction(Triangle)
返回3。请注意这项工作仅适用于case class
es,因为真实的,我们在这里传递的不是类本身,而是自动生成的companion object
但更常见的是没有必要定义类,你可以在除顶级事物之外的任何上下文中编写,就像
一样def square() = new Shape{
def sides() = 4
}
def triangle() = new Shape{
def sides() = 3
}
下一步:具有空参数列表的方法通常读作具有副作用的方法。因此,定义类型
更方便sealed trait Shape{
def sides:Int
}
如果你定义你的构建器
def square = new Shape{
def sides = 4
}
def triangle = new Shape{
def sides = 3
}
你应该将它们用作someFunction(square _)
告诉你,你要使用方法调用而不是它返回的值
最后一件事是:如果你真的需要代码,那就创建了一些对象,但它可能包含复杂的计算,资源处理或一些可能的异常,所以你想要保持它的执行,直到它真的需要,你可以使用等同于R的call-by-name parameters,我假设你熟悉
答案 2 :(得分:0)
除非shape
具有apply
功能,否则您无法在()
对象上调用shape
。
如果您想将aShape
分配给a
,只需撰写val aShape = a
。
但由于我没有看到附加值,您可以直接在sides
上调用a
函数:
def someFunction(a:shape) = {
val sides = a.sides
// use sides
}
答案 3 :(得分:0)
这是你写的最接近的翻译:
sealed trait Shape {
def sides: Int
}
case object Square extends Shape {
override val sides = 4
}
case object Triangle extends Shape {
override val sides = 3
}
def someFunction(a: Shape) =
val shapeSides = a.sides
一些注意事项:
a: Shape
,则表示a
是Shape
,并且您尚未定义任何可让您在其上调用()
的内容。 def
覆盖val
(如果它是静态的)