正确使用scala特性和类型
scala新手,试图掌握类系统的窍门。下面是一个简单的设置:正确使用scala特性和类型,scala,Scala,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()方法,并使用该方法 d
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
的上下文中-我想将一个类传递给一个函数,并实例化该类的一个对象,然后对该对象执行一些操作。谢谢您的帮助。除非shape
具有apply
功能,否则您不能对shape
对象调用()
如果要将aShape
分配给a
,只需编写val aShape=a
但由于我没有看到附加值,您不妨直接在a
上调用sides
函数:
def someFunction(a:shape) = {
val sides = a.sides
// use sides
}
你想用那行代码做什么?您已经有了一个
形状
,传入的形状名为a
。只需删除该行并调用a.sides()
在风格上,有几个问题。首先,类名应该以大写字母开头。其次,
sides
似乎是一个不可变的属性,而不是一个变异的方法,因此应该声明并重写它,而不使用括号。您还需要在子类中使用override
修饰符。最后,您可以不使用空括号:{4}
应该是4
这是您所写内容的最接近的翻译:
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
一些注意事项:
- scala中的类应该是CamelCase
- 子类没有实例成员,因此可以使用单例对象
- 如果您有
,则表示a:Shape
是a
,并且您还没有定义任何可以调用Shape
的内容()
- 当内部只有一个表达式时,可以省略大括号
- 如果是静态的,可以使用
覆盖val
def
- 有几种方法可以做到这一点。一个是复杂的,第二个稍微简单一点,第三个是最简单的。
只需将
someFunction
的定义更改为
def someFunction(a: ()=>Shape)={
val aShape = a()
aShape.sides
}
所以someFunction(Square)
return4
和someFunction(Triangle)
返回3。请注意,这只适用于case类
es,因为我们在这里传递的实际内容不是类本身,而是自动生成的
但更常见的情况是,不需要定义类,您可以在任何上下文中编写,顶层除外,就像
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的代码,我想你熟悉它,它是一个值,不是函数、方法、构造函数……感谢您的帮助。我意识到在这个例子中,创建
someFunction
是过分的,因为sides()
可以直接从对象访问。但是我的主要问题是在someFunction
的上下文中-我想向该函数传递一个类,并实例化该类的一个对象,然后对该对象执行一些操作。我会澄清这个问题。你通常不会先传入一个类,然后创建一个实例,而是传入一个实例。是否要根据输入的边数创建实例?你想解决的真正问题是什么?谢谢,我一直在想这个错误,这有助于澄清我的理解。我将尝试提出一个我实际问题的简洁版本。