如何在Scala中关闭特定的隐式代码,以防止由于重载方法而导致代码无法编译? [英] How to turn off specific Implicit's in Scala that prevent code from compiling due to overloaded methods?

查看:104
本文介绍了如何在Scala中关闭特定的隐式代码,以防止由于重载方法而导致代码无法编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正忙于自己回答这个问题: https: //objectpartners.com/2013/04/24/html-encoding-utf-8-characters/

所以我决定在Scala中重写示例:

  def htmlEncode(input: String) = htmlEncode_sb(input).toString

  def htmlEncode_sb(input: String, stringBuilder: StringBuilder = new StringBuilder()) = {
    for ((c, i) <- input.zipWithIndex) {
      if (CharUtils.isAscii(c)) {
        // Encode common HTML equivalent characters
        stringBuilder.append(StringEscapeUtils.escapeHtml4(c.toString()))
      } else {
        // Why isn't this done in escapeHtml4()?
        stringBuilder.append(String.format("&#x%x;": String, Character.codePointAt(input, i)))
      }
    }
    stringBuilder
  }
}

仅供参考:如果我已经使用另一个StringBuilder构建了某些东西,那么我倾向于将大多数对String有用的东西重写为一个包装好的StringBuilder调用,在这种情况下,我可以将该StringBuilder作为参数进行传递-如果则不能通过调用第一个函数来作为普通的String.

您会认为这一切都很好,但Scala编译器的说法是:

[info] Compiling 1 Scala source to /SomeOne/SomePath/SomeProject/target/scala-2.11/classes...
[error] /SomeOne/SomePath/SomeProject/TKEmailAgent.scala:278: overloaded method value format with alternatives:
[error]   (x$1: java.util.Locale,x$2: String,x$3: Object*)String <and>
[error]   (x$1: String,x$2: Object*)String
[error]  cannot be applied to (String, Int)
[error]         stringBuilder.append(String.format("&#x%x;": String, Character.codePointAt(input, i)))
[error]                                     ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

请注意,我什至尝试声明"第一个需要为字符串的参数:

stringBuilder.append(String.format("&#x%x;": String, Character.codePointAt(input, i)))

,但是编译器没有暗示使用java.util.Locale的重载方法可以解决问题.

我把代码移到了一个不太混乱的类上,以为也许这样做很重要,但是没有运气.

所以问题是,如何禁用非个人选择的隐式行为?

OR

如何满足编译器知道您在这里真正想要的需求?

解决方案

您的问题与隐式*无关,而与Scala Int不是Object的事实无关.错误消息告诉您真相:String.format具有两个重载,并且您的参数列表与两个重载都不匹配.

尝试使用Int.box(Character.codePointAt(input, i))将参数设置为Object.

*好吧,它与隐式有一点关系,因为Int可以隐式转换为Integer,但是不会应用于将Int转换为Object. /p>

I'm busy trying to answer this question myself: Scala Play 2.4.x handling extended characters through anorm (MySQL) to Java Mail

and I came across this possible solution: https://objectpartners.com/2013/04/24/html-encoding-utf-8-characters/

So I decided to rewrite the sample in Scala:

  def htmlEncode(input: String) = htmlEncode_sb(input).toString

  def htmlEncode_sb(input: String, stringBuilder: StringBuilder = new StringBuilder()) = {
    for ((c, i) <- input.zipWithIndex) {
      if (CharUtils.isAscii(c)) {
        // Encode common HTML equivalent characters
        stringBuilder.append(StringEscapeUtils.escapeHtml4(c.toString()))
      } else {
        // Why isn't this done in escapeHtml4()?
        stringBuilder.append(String.format("&#x%x;": String, Character.codePointAt(input, i)))
      }
    }
    stringBuilder
  }
}

FYI: I tend to re-write most things that work on Strings into a wrapped StringBuilder call in case I'm already building something with another StringBuilder in which case I can just pass that StringBuilder as a param - if not then works as a normal String by calling the first function.

You would think this is all fine and dandy however the Scala compiler has this to say:

[info] Compiling 1 Scala source to /SomeOne/SomePath/SomeProject/target/scala-2.11/classes...
[error] /SomeOne/SomePath/SomeProject/TKEmailAgent.scala:278: overloaded method value format with alternatives:
[error]   (x$1: java.util.Locale,x$2: String,x$3: Object*)String <and>
[error]   (x$1: String,x$2: Object*)String
[error]  cannot be applied to (String, Int)
[error]         stringBuilder.append(String.format("&#x%x;": String, Character.codePointAt(input, i)))
[error]                                     ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

Note that I even tried "declaring" the first parameter needed to be a string:

stringBuilder.append(String.format("&#x%x;": String, Character.codePointAt(input, i)))

and yet the compiler didn't take the hint that the overloaded method with a java.util.Locale would do the trick.

I moved the code to a less cluttered class thinking perhaps it was an import doing this but no such luck.

So the question is how does one disable Implicit's that are not of one's choosing?

OR

How does one satisfy the compiler's need to know what you really want here?

解决方案

Your problem has nothing to do with implicits* and everything to do with the fact that a Scala Int is not an Object. The error message is telling you the truth: String.format has two overloads and your parameter list doesn't match either of them.

Try using Int.box(Character.codePointAt(input, i)) to make your parameter into an Object.

*Okay, it has a little to do with implicits, in that an Int can be implicitly converted to an Integer, but that won't be applied to convert an Int to Object.

这篇关于如何在Scala中关闭特定的隐式代码,以防止由于重载方法而导致代码无法编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆