2017-07-01 37 views
0

我正在使用Scala bCrypt wrapper來加密用戶密碼,這個包裝提供了一個隱式類。Scala隱式類成員不能在對象中訪問

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() 
} 

但我面臨着一個奇怪的問題,每當我用這隱含converision在它workes罰款,但converiosn不工作與對象case類

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> 

我不知道我在做什麼錯在這裏。

回答

2

任何穩定標識符陰影導入implicit標識符。可能影響隱含的事物包括valdef,object和生成的伴侶對象case class。簡單的class es和type s不會創建標識符,因此不會影響導入的implicit標識符。

implicit class Password僅僅是一個class Passwordimplicit def Password,因此,在您的命名Password代碼標識將影子implicit def語法糖。

所以,儘管這個代碼編譯OK:

object Foo { 
    import bcrypt._ 
    class Password() 
    "123".bcrypt 
} 
以下所有片段的

將無法​​編譯:

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 
} 

你的情況的解決方法很簡單:隱類重命名爲別的東西,那將不太可能與其他標識符衝突。例如,implicit class PasswordExtensions

如果您不能重命名在原代碼implicit class,你可以進口它以不同的名稱:import com.github.t3hnar.bcrypt.{Password => PasswordExtensions, _}

+0

好了,原來這是「密碼」的碰撞作爲標識符是造成這編譯失敗,它的工作原理是隻改變這個語句import com.github.t3hnar.bcrypt。{Password => BcryptUtil} –