0
votes

I have external service which returns AnyRef I want to cast result to Boolean, or return false if return is not Boolean.

Here is a example:

object ExternalService {

  def sendEvent(s: String) : AnyRef = {
    return true   } 
  }

object Caller {

  def isValid(s: String): Boolean = {

    val value = ExternalService.sendEvent("test")
    value match {
      // pattern type is incompatible with expected type found Boolean expected AnyRef
      case b: Boolean => b
      case _ => false
    }   
  } 
}

but i got

Error:(6, 12) the result type of an implicit conversion must be more specific than AnyRef return true; Error:(6, 12) type mismatch; found : Boolean(true) required: AnyRef return true; Error:(17, 15) pattern type is incompatible with expected type; found : Boolean required: Object case b: Boolean => b

How can I cast AnyRef to Boolean in this case or in general?

1
Try matching on java.lang.Boolean instead - unlike scala's version, that doesn't inherit from AnyVal so should work.Astrid

1 Answers

2
votes

Two problems with your code:

The first is that you're trying to return true from a method returning AnyRef. However, scala.Boolean isn't of that type (it inherits from AnyVal instead) and the compiler is not happy to be asked to find an implicit conversion to "any reference type". Either you need to change your method to return Any, or you need to make sure to return the "boxed" Boolean reference type - java.lang.Boolean - instead.

Same for the match statement - there's no way for a value of type AnyRef to be scala.Boolean, and you don't have access to a lot of implicit conversion logic in a pattern match statement. Again, if you use Any instead of AnyRef everything will work.

So the working version of your code:

object ExternalService {

  def sendEvent(s: String) : Any = {
    true
  }
}

object Caller {

  def isValid(s: String): Boolean = {

    val value = ExternalService.sendEvent("test")
    value match {
      // pattern type is incompatible with expected type found Boolean expected AnyRef
      case b : Boolean => b
      case _ => false
    }
  }
}

or, if you really need the return type of sendEvent to be AnyRef:

object ExternalService {

  def sendEvent(s: String) : AnyRef = {
    Boolean.box(true)
  }
}

object Caller {

  def isValid(s: String): Boolean = {

    val value = ExternalService.sendEvent("test")
    value match {
      // pattern type is incompatible with expected type found Boolean expected AnyRef
      case b : java.lang.Boolean => b
      case _ => false
    }
  }
}

(The compiler can manage the conversion from java.lang.Boolean to scala.Boolean in the output of the match statement, so you don't need to explicitly unbox there.)