简体   繁体   中英

Scala doesn't recognize implicit conversion

I'm trying to define an additional method on Scala's Try via implicit conversions. Here's my isolated, reproducible example--

import scala.util.Try

object App {
  def main(args: Array[String]): Unit = {
    val t = Try(2)
    t.getOrThrow()
  }
}

trait TrySyntax {
  implicit final def trySyntax[A](t: Try[A]): TryOps[A] = new TryOps(t)
}

final class TryOps[A](val t: Try[A]) extends AnyVal {
  def getOrThrow(): A = t.getOrElse(throw t.failed.get)
}

I'm running into the following compile error.

error: value getOrThrow is not a member of scala.util.Try[Int]
    t.getOrThrow(

Does anyone know what I'm doing wrong? The explicit conversion-- trySyntax(t).getOrThrow works fine. I've tried importing scala.languageFeatures.implicitConversions but didn't help. I also originally had the implicit conversion in its own package that was imported as import mypackage._ but that yielded the same result.

You are pretty close, and have two options to resolve this.

1. Your implicit conversion contained in the TrySyntax trait is not available in your App's main method. You need to import it. This requires the TrySyntax trait to become an object.

import scala.util.Try

object App {
  def main(args: Array[String]): Unit = {
    import TrySyntax._
    val t = Try(2)
    t.getOrThrow()
  }
}

object TrySyntax {
  implicit final def trySyntax[A](t: Try[A]): TryOps[A] = new TryOps(t)
}

final class TryOps[A](val t: Try[A]) extends AnyVal {
  def getOrThrow(): A = t.getOrElse(throw t.failed.get)
}

2. Make TryOps class implicit. Implicit class is similar to implicit method - given some t: Try[A] , it will construct an (implicit) value of type TryOps[A] . Added feature of an implicit class is that it can define method(s) available on the newly created implicit object (in your case getOrThrow() ). Note that implicit class must have exactly one argument in the constructor, which makes sense. Also note that implicit class cannot exist on its own, so you should move it to a trait or object (moving it to object App makes the most sense for your example).

object App {
  def main(args: Array[String]): Unit = {
    val t = Try(2)
    t.getOrThrow()
  }

  final implicit class TryOps[A](val t: Try[A]) extends AnyVal {
    def getOrThrow(): A = t.getOrElse(throw t.failed.get)
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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