首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >创建经过消毒的字符串类型时的对称相等(使用scala.Proxy)

创建经过消毒的字符串类型时的对称相等(使用scala.Proxy)
EN

Stack Overflow用户
提问于 2017-01-18 05:39:14
回答 3查看 154关注 0票数 11

我有一个scala (2.10.4)应用程序,其中电子邮件地址被大量传递,我想实现一个在IO调用的抽象来“清理”已经验证的电子邮件地址。

使用scala.Proxy几乎就是我想要的,但是我遇到了不对称相等的问题。

代码语言:javascript
运行
复制
    class SanitizedEmailAddress(s: String) extends Proxy with Ordered[SanitizedEmailAddress] {
  val self: String = s.toLowerCase.trim

  def compare(that: SanitizedEmailAddress) = self compareTo that.self
}

object SanitizedEmailAddress {
  def apply(s: String) = new SanitizedEmailAddress(s)
  implicit def sanitize(s: String): SanitizedEmailAddress = new SanitizedEmailAddress(s)
  implicit def underlying(e: SanitizedEmailAddress): String = e.self
}

我想要一份

代码语言:javascript
运行
复制
val sanitizedEmail = SanitizedEmailAddress("Blah@Blah.com")
val expected = "blah@blah.com"
assert(sanitizedEmail == expected) // => true
assert(expected == sanitizedEmail) // => true, but this currently returns false :(

或者具有类似功能的东西。有什么不麻烦的方法可以做到这一点吗?

代码语言:javascript
运行
复制
    assert(sanitizedEmail.self == expected) // => true (but pretty bad, and someone will forget)
// can have a custom equality method and use the "pimp-my-lib" pattern on strings, but then we have to remember to use that method every time

谢谢你的帮助。

EN

回答 3

Stack Overflow用户

发布于 2017-02-07 19:59:23

我不认为这是可能的,对不起。

我也不确定这样做是不是对的。如果String真的等于SanitizedEmailAddress,那么SanitizedEmailAddress包装器实际上表示什么?

我认为更一致的做法是让String不能与SanitizedEmailAddress相提并论,并要求用户在比较输入之前对其进行“消毒”。

票数 3
EN

Stack Overflow用户

发布于 2017-02-08 03:13:16

您希望使用标记特征来表示符合的字符串。

接受Email字符串的函数知道该字符串是正确的。

如果将普通字符串与Email字符串进行比较,则它也必须是正确的。

代码语言:javascript
运行
复制
package object email {
  type Tagged[U] = { type Tag = U }
  type @@[T, U] = T with Tagged[U]
  def smartly[A](s: String): String @@ A = Email(s).asInstanceOf[String @@ A]
}

package email {
  trait Email extends Any
  object Email {
    def apply(s: String) = s.toLowerCase.trim
  }
  object Test extends App {
    def f(ok: String @@ Email) = {
      assert(ok.forall(c => !c.isLetter || c.isLower))
    }
    val x = smartly[Email]("Joe@ACME.com")

    println(x)
    f(x)
    assert("joe@acme.com" == x)
/*
    f("Junk@Yahoo.com")  // DNC
email.scala:22: error: type mismatch;
 found   : String("Junk@Yahoo.com")
 required: email.@@[String,email.Email]
    (which expands to)  String with AnyRef{type Tag = email.Email}
    f("Junk@Yahoo.com")
      ^
one error found
*/
  }
} 
票数 2
EN

Stack Overflow用户

发布于 2017-02-13 03:55:13

如何保持所有的电子邮件类型为字符串,并隐式地拉皮条‘清理’信息:

代码语言:javascript
运行
复制
object SanitizedEmailAddress {
  def apply(s: String): String = synchronized {
    val verified = s.toLowerCase.trim
    sanitized.update(verified, true)
    verified
  }

  def isSanitized(s: String): Boolean = synchronized {
    sanitized.contains(s)
  }

  private val sanitized = scala.collection.mutable.WeakHashMap.empty[String, Boolean]
}

implicit class emailOps(val email: String) extends AnyVal {
  def isSanitized: Boolean = SanitizedEmailAddress.isSanitized(email)
}

现在:

代码语言:javascript
运行
复制
val sanitizedEmail = SanitizedEmailAddress("Blah@Blah.com")
val expected = "blah@blah.com"
assert(sanitizedEmail == expected) // => true
assert(expected == sanitizedEmail) // => true

assert(sanitizedEmail.isSanitized == true) // => true
assert("blah@blah.com".isSanitized == true) // => true
assert("Blah@Blah.com".isSanitized == false) // => true
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41707483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档