2017-07-01 2 views
0

Ich benutze Scala bCrypt wrapper zum Verschlüsseln von Benutzerkennwort, bietet dieser Wrapper eine implizite Klasse.Scala Implizite Klasse Mitglied ist nicht zugänglich in Objekt

package object bcrypt { 

    implicit class Password(val pswrd: String) extends AnyVal { 
    def bcrypt: String = B.hashpw(pswrd, BCrypt.gensalt()) 

    def bcrypt(rounds: Int): String = B.hashpw(pswrd, BCrypt.gensalt(rounds)) 

    def bcrypt(salt: String): String = B.hashpw(pswrd, salt) 

    def isBcrypted(hash: String): Boolean = B.checkpw(pswrd, hash) 
    } 

    def generateSalt: String = B.gensalt() 
} 

Aber ich bin ein seltsames Problem konfrontiert, wenn ich diese Implizite converision in Klasse bin mit es workes in Ordnung, aber converiosn funktioniert nicht mit Objekt oder Fallklassen.

scala> import com.github.t3hnar.bcrypt._ 
import com.github.t3hnar.bcrypt._ 

scala> class Password(secret: String) { 
    | def validate(userSecret: String): Boolean = userSecret.isBcrypted(secret) 
    | 
    | override def toString = secret 
    | } 
defined class Password 

scala> object Password { 
    | def apply(secret: String): Password = new Password(secret) 
    | 
    | def getEncrypted(secret: String) = new Password(secret.bcrypt) 
    | } 
<console>:18: error: value bcrypt is not a member of String 
     def getEncrypted(secret: String) = new Password(secret.bcrypt) 
                   ^

scala> 

Ich bin mir nicht sicher, was ich hier falsch mache.

Antwort

2

Alle stabilen Bezeichner-Schatten wurden importiert implicit Bezeichner. Dinge, die Schatten implicits können gehören val, def, object und das generierte Companion-Objekt case class. Simple class es und type s Kennungen nicht erstellen und daher keine importierten implicit Kennungen.

implicit class Password ist nur syntaktischer Zucker für ein class Password und ein implicit def Password, und so eine Kennung in Ihrem Code namens Password würde diese implicit def Schatten.

So, während dieser Code kompiliert OK:

object Foo { 
    import bcrypt._ 
    class Password() 
    "123".bcrypt 
} 

Alle folgenden Schnipsel wird nicht kompilieren:

object Foo2 { 
    import bcrypt._ 
    val Password = 1 
    "123".bcrypt 
} 

object Foo3 { 
    import bcrypt._ 
    def Password() = 1 
    "123".bcrypt 
} 

object Foo4 { 
    import bcrypt._ 
    case class Password() 
    "123".bcrypt 
} 

object Foo5 { 
    import bcrypt._ 
    object Password 
    "123".bcrypt 
} 

Die Lösung in Ihrem Fall ist einfach: benennen Sie die impliziten Klasse etwas anderes Es wäre unwahrscheinlich, dass dies mit anderen Identifikatoren kollidiert. Zum Beispiel implicit class PasswordExtensions.

Wenn Sie nicht die implicit class im ursprünglichen Code umbenennen, können Sie Import es unter einem anderen Namen: import com.github.t3hnar.bcrypt.{Password => PasswordExtensions, _}

+0

Ok, so stellt sich heraus, es war Kollision von „Password“ als Kennung verursacht wurde diese Kompilierungsfehler, funktioniert es nur durch Ändern dieser Anweisung import com.github.t3hnar.bcrypt. {Password => BcryptUtil} –

Verwandte Themen