Scala类型关键字:如何最好地在多个类中使用它


71

在写完Haskell拼写之后回到Scala,我开始使用type关键字使我的类定义更具可读性,例如:

type RestfulParams = Map[String, String]
def canonicalize(params: RestfulParams): String = { ... }

我遇到的麻烦是这些类型定义需要存在于类或对象中-它们不是像Haskell中那样的“一流公民”。如果我尝试在类或对象之外定义类型,则会得到编译器expected class or object definition

那么我的问题是如何在包中的多个类和对象之间使用这些类型?我现在所做的事情看起来很丑陋:

object RestfulTypes { type RestfulParams = Map[String, String] etc }

然后在另一个类文件中:

import utils.{RestfulTypes => RT}
def get(resource: String, params: RT.RestfulParams): String = { ... }

有没有更好的方法可以做到-顺便问一下,Scala专家认为类型只能在类/对象中定义是好事还是坏事?


9
为什么不import utils.RestfulTypes._呢?
SOC

Answers:


71

包对象对你的工作?

从文章:

在2.8版之前,您只能在包中放入类,特征和独立对象。到目前为止,这些是放在软件包顶层的最常见的定义,但是Scala 2.8并不仅限于此。您可以在类中放入任何定义,也可以将其放在包的顶层。如果您想使用某种辅助方法,则希望将其放在整个程序包的范围内,请继续将其放在程序包的顶层。为此,您将定义放在包对象中。每个包都允许有一个包对象。放置在包对象中的所有定义均视为包本身的成员。

包对象的Scala有许多类型和值了,所以我认为你可以使用同样的技术为自己的类型。


11

在这种情况下,我不确定什么构成好看的东西,但是有两个选择:

使用特质:(Scala的无私特质模式

trait RestfulTypes {
  type Params = Map[String,String]
  //...
}

object MyRestService extends RestService with RestfulTypes { /* ... */ }

或者只是导入对象的成员,像打包一样有效地使用它:

import util.RestfulTypes._

1
@agilesteel:该链接不应该是第一个,因为它仅属于第一个选项,请在编辑时不要更改我的回答的含义。
Kim Stebel,2011年

谢谢,无私的特质模式非常酷。我意识到我已经看到了使用它的各种Scala框架和工具,只是没有意识到它是什么。再次感谢您的回答。
Alex Dean

@Kim:对不起,不会再发生了。
agilesteel 2011年

7

您可以使用包对象,然后在其中放置类型声明。当您导入该程序包时,类型定义将可用。

一个例子 :

//package myType
package object myType {type mine = List[String]}

请注意,包对象具有与包相同的名称,以便可以在没有对象前缀的情况下使用,即myType.mine如果使用其他名称来命名它,例如:

//package myType
package object mainType {type mine = List[String]}

导入“包”时,可以使用mainType.mine访问它

有关更多信息:http : //www.scala-lang.org/docu/files/packageobjects/packageobjects.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.