简体   繁体   English

具有隐式类Scala的特征

[英]Traits With implicit Class Scala

On my example. 在我的例子中。 I want to find a way to use Implicit value in my connection to aws-sns. 我想找到一种在aws-sns的连接中使用隐式值的方法。

object SNSClient {

}

class SNSClient {
  val region =
    try {
      val prop = new Properties()
      prop.load(new FileInputStream("config.properties"))
      prop.getProperty("aws.region")
    } catch {
      case e: Exception => println("error")
    }

 // In this method Scala wont compile
 def providesSNSClient(): AmazonSNS = {
      AmazonSNSClientBuilder
             .standard
             .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey.toString(), secretKey.toString())))
             .withRegion(region) //Error compile
             .build()
  }
}

 /**
  * Rich prpierties
  */
 trait RegionsImplict {
   /**
    * Return default value if it does not provide Regions.EU_WEST_1
    */
   implicit class RegionB(region: String){
     def asRegion: Regions = Regions.values().find(_.name == region).getOrElse(Regions.EU_WEST_1)
   }

 }

So far so good I want to call my function asRegion on my line code .withRegion(region)//Error compile 到目前为止,到目前为止,我想在行代码.withRegion(region)// Error编译中调用函数asRegion

The problem here is that region is NOT a String , so the implicit conversion doesn't kick in. 这里的问题是region不是String ,所以隐式转换不会启动。

You can see this with the following simplified Scala REPL example: 您可以通过以下简化的Scala REPL示例看到这一点:

scala> val region = try { "value" } catch { case e: Exception => println("error") }
region: Any = value  // <--- notice type is Any

Why? 为什么? Because some of the code paths (ie the catch phrase) do not product a String, so the compiler has to "settle" for the closest common supertype, which is Any . 由于某些代码路径(即catch短语)不产生String,因此编译器必须“解决”最接近的公共超类型,即Any

To fix this, you should either abort on exception, or provide some default value, otherwise some code paths simply won't produce a String. 为了解决这个问题,您应该要么异常中止,要么提供一些默认值,否则某些代码路径根本不会产生String。 For example: 例如:

val region =
  try {
    val prop = new Properties()
    prop.load(new FileInputStream("config.properties"))
    prop.getProperty("aws.region")
  } catch {
    case e: Exception => println("error"); "us-east" // Default!
  }  

NOTE : as commented, it is not recommended to use implicit conversions so lightly, especially for common types such as Strings - they might kick in when you don't expect them to and make code harder to read. 注意 :正如所评论的那样,不建议轻率地使用隐式转换, 尤其是对于诸如字符串之类的常见类型-可能会在您不希望它们发生时使它们插入,并使代码难以阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM