Как я могу явно вернуть Unit? - PullRequest
0 голосов
/ 21 ноября 2018

Как правильно явным образом вернуть тип Unit из метода, используя () или Unit?Мне кажется, что оба работают во всех случаях, которые я пробовал сам.

Для контекста это часто происходит, если я пишу метод с побочными эффектами и возвращает Unit, который вызывает другой метод, который такжевыполняет побочные эффекты, но возвращает некоторое значение вместо Unit.Например,

def effectAndReturn(): String = {
  val msg = "Hello, SO"
  println(msg)
  msg
}

def doEffect(): Unit = {
  val _ = effectAndReturn()
  () // `Unit` also works here
}

Насколько я понимаю, () является единственным значением типа Unit, которое существует.Возвращение токена Unit в doEffect() ссылается на сопутствующий объект Unit;Я запутался, как это будет возвращать значение, так как там даже не определен метод apply.Насколько мне известно, возвращение объекта-компаньона для данного типа абстрактного класса недопустимо в качестве возвращаемого значения.

Вставить их в Scala REPL также интересно

scala> val parenUnit = ()
parenUnit: Unit = ()

scala> parenUnit
// Returns blank line

scala> val wordUnit = Unit
wordUnit: Unit.type = object scala.Unit

scala> wordUnit
res1: Unit.type = object scala.Unit

scala> res1
res2: Unit.type = object scala.Unit

() это просто значение Unit, тогда как Unit возвращает тип, который не имеет смысла для меня, поскольку никакие другие сопутствующие объекты не делают этого, насколько я могу судить.Я предполагаю, что компилятор обрабатывает Unit особым и уникальным способом по сравнению с любым другим типом, но как именно?

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Предположим, у нас есть два метода в классе с именем TestUnit:

class TestUnit {
  def foo(): Unit = 2217
  def bar(): Int = 1478
}

Давайте посмотрим на его байт-код:

  // access flags 0x1
  public foo()V
   L0
    LINENUMBER 4 L0
    SIPUSH 2217
    POP
    RETURN // returns void
   L1
    LOCALVARIABLE this Lunit/TestUnit; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public bar()I
   L0
    LINENUMBER 5 L0
    SIPUSH 1478
    IRETURN // returns integer because it is declared in method
   L1
    LOCALVARIABLE this Lunit/TestUnit; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

Я предполагаю, что компилятор Scala просто поставил RETURN инструкция (которая возвращает void) в каждом методе, где Unit объявлен как возвращающий тип.(вы можете посмотреть списки здесь )

Так что вы можете вернуть любой тип в doEffect().Но, как сказал @ ghik , лучше использовать ().

0 голосов
/ 21 ноября 2018

Итак, у нас есть:

  • Тип Unit
  • Значение единицы, т. Е. () типа Unit
  • Объект-компаньон Unit, вызывающий путаницу.Это не типа Unit.Он имеет тип Unit.type (свой собственный тип синглтона).Однако ... Scala автоматически неявно преобразует все в Unit, и поэтому вы можете использовать его там, где ожидается тип Unit.

TLDR: Использовать ()

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