Ключевое слово типа Scala: как лучше всего использовать его в нескольких классах - PullRequest
70 голосов
/ 16 сентября 2011

Возвращаясь к Scala после написания заклинания на Haskell, я начал использовать ключевое слово 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думаете, это хорошо или плохо, что типы могут быть определены только внутри классов / объектов?

Ответы [ 3 ]

71 голосов
/ 16 сентября 2011

Будут ли объекты пакета работать на вас?

Из статьи:

До версии 2.8 единственными вещами, которые вы могли поместить в пакет, были классы,черты и отдельные объекты.Это, безусловно, самые распространенные определения, которые размещаются на верхнем уровне пакета, но Scala 2.8 не ограничивает вас только этими.Любое определение, которое вы можете поместить в класс, вы также можете поместить на верхний уровень пакета.Если у вас есть какой-то вспомогательный метод, который вы хотели бы использовать в рамках всего пакета, продолжайте и поместите его прямо на верхний уровень пакета.Для этого вы помещаете определения в объект пакета.Каждому пакету разрешено иметь один объект пакета.Любые определения, помещенные в объект пакета, считаются членами самого пакета.

объект пакета scala уже имеет много типов и значений, поэтому я думаю, что вы можете использовать ту же техникудля ваших собственных типов.

11 голосов
/ 16 сентября 2011

Я не уверен, что представляет собой милость в этом случае, но есть два варианта:

Использование черты: ( Модель самоотверженной черты Scala )

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

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

Или просто импортируйте элементы объекта, эффективно используя его как пакет:

import util.RestfulTypes._
7 голосов
/ 02 мая 2013

Вы можете использовать объект пакета и поместить туда объявление типа.При импорте этого пакета будет доступно определение типа.

Пример:

//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 / document /файлы / packageobjects / packageobjects.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...