2017-02-20 22 views
3

Рассмотримдругу в Scala

  • функция f определена в пакете p1

  • пакет p2, который не содержит p1

  • пакет p3, который не содержит p2 или p1 ни он не содержится в p2 или p1.

В Scala, можно заявить, что f доступен из пакета p2, но не из других пакетов (например, p3)?

+0

Теперь, когда я думаю об этом, каким-то образом можно использовать объекты пакета и implicits, импортируя некоторые импликации в объект пакета (находясь в 'p2') и требуя, чтобы он присутствовал при вызове' f' (требуя это в 'f' как аргумент). – jhegedus

ответ

1

Если я растягиваю ваши правила до пределов, это возможно. Хотя я не уверен, что это задумано или что вы забыли правило.

scala> :paste -raw 
// Entering paste mode (ctrl-D to finish) 

package p1 { 
    object O { private[p1] def f = println("f") } 

    package p2 { 
    object O { def x = p1.O.f } 
    } 
} 

// Exiting paste mode, now interpreting. 


scala> :paste -raw 
// Entering paste mode (ctrl-D to finish) 

package p3 { 
    object O { def x = p1.O.f } 
} 

// Exiting paste mode, now interpreting. 

<pastie>:2: error: method f in object O cannot be accessed in object p1.O 
    object O { def x = p1.O.f } 
         ^
There were compilation errors! 

Если p2 также не может содержаться p1, я не думаю, что есть способ, чтобы гарантировать, что f не может быть доступна из других. Вы можете сделать некоторые трюки с запечатанными чертами и имплицитами.

package p2 { 
    object O { def x = p1.O.f } 
} 

package object p2 { 
    sealed trait Friend 
    private[p2] implicit val p2Friend: Friend = new Friend {} 
} 

package p1 { 
    object O { def f(implicit friend: p2.Friend) = println("f") } 
} 

package p3 { 
    object O { def x = p1.O.f(null) } 
} 

Но теперь, как вы можете видеть, вы можете обмануть в пакет p3. И без обмана f невозможно получить доступ к p1 сам, потому что p1 также не имеет необходимого неявного.

Вы можете зарегистрироваться f: friend is null. Тогда p3 не может действительно использовать f, но он будет работать только во время выполнения, а не во время компиляции. Хотя, если кто-то проезжает около null, они не могут действительно жаловаться, если во время выполнения вещи взорвутся.

+0

Ницца! Благодарю. Нулевой параметр интересен, это заставляет меня задаться вопросом: нет ли аннотации, которая дает ошибку компилятора при передаче значения null в параметр? – jhegedus

+0

Хм ... кажется устаревшим .... NotNull, то есть. – jhegedus

+0

Вы можете попробовать некоторые вещи с помощью 'AnyVal', так как только' AnyRef' может быть нулевым. Но я думаю, что все равно будет возможно «null.asInstanceOf [p2.Friend]». –