Разница между этим и самим собой в аннотациях типа себя?

134

В различной литературе по Scala я вижу некоторые аннотации самостоятельного типа, использующие «this», а другие - «self»:

trait A { this: B => ... }
trait A { self: B => ... }

Есть ли реальная разница между использованием «этого» или «себя»? Имеет ли значение какое имя вы используете? Это так же верно?

trait A { foo: B => ... }
Zach
источник

Ответы:

181

Все три формы являются действительными и имеют эффект, который Bпредполагается в качестве типа thisв классе A.

Первые два варианта

trait A { self: B => ... }
trait A { foo: B => ... }

ввести self(соответственно foo) в качестве псевдонима для thisпризнака A. Это полезно для доступа к thisссылке из внутреннего класса. Т.е. вы можете использовать selfвместо A.thisдоступа к thisссылке на черту Aкласс, вложенный в него. Пример:

class MyFrame extends JFrame { frame =>    
  getContentPane().add( new JButton( "Hide" ) {
    addActionListener( new ActionListener {
      def actionPerformed( e: ActionEvent ) {
        // this.setVisible( false ) --> shadowed by JButton!
        frame.setVisible( false )
      }
    })
  })
}

Третий вариант,

trait A { this: B => ... }

не вводит псевдоним для this; он просто устанавливает сам тип.

Мартин Одерский
источник
То, как я смотрю на тип self, заключается в том, что признак объявил себя как принимающий определенный тип и возвращающий блок кода, например, foo: B => {...}. Теперь эти завитки, конечно, опущены. Интересно видеть, что вы можете использовать имя объекта вместо «this» в любой области кода, хотя [что-то, что мы делаем все время в javascript]
Устаман Сангат
4
@ Мартин Одерский Можно ли добавить ограничение для двух или более черт, что-то вроде trait A { self: B, C => ... }?
Дмитрий Беспалов
13
@DmitryBespalov: Да, вы можете использовать withключевое слово в аннотации для самостоятельного ввода текста. Напримерtrait A { self: B with C => ... }
Дейв
Кстати, вы также можете сделать _: B =>для случая не псевдоним для простоты
Creos
17

Существует различие в том, что thisвсегда относится к объекту, определенному самым внутренним шаблоном.

Выражение thisможет появиться в части оператора шаблона или составного типа. Он обозначает объект, определяемый самым внутренним шаблоном или составным типом, включающим ссылку. Если это составной тип, тип thisявляется этим составным типом. Если шаблон класса или объекта определения с простым именем C , тип это то же самое , как тип C . this, (Ссылка Scala §6.5)

Итак, если вы называете свой тип foo, вы все равно можете ссылаться на него как this(если, конечно, вы не находитесь во внутреннем шаблоне, в этом случае thisбудете ссылаться на определенный им объект - и если вы не дадите внутренний шаблон самостоятельно набирает то же имя), но, очевидно, не наоборот.

Debilski
источник