How to convert Scala Int to Double?

val d: Double = 42 

When I try to find an implicit conversion through intellij, nothing interesting comes up. In addition, Int not a subtype of Double . So how to do Scala?

+5
source share
1 answer

In short: this is not an ordinary implicit conversion on some companion object, numerical types will receive special treatment.


If we run scala -print on this script:

 val d: Double = 42 

we get:

 package <empty> { object Main extends Object { def main(args: Array[String]): Unit = { new <$anon: Object>(); () }; def <init>(): Main.type = { Main.super.<init>(); () } }; final class anon$1 extends Object { private[this] val d: Double = _; <stable> <accessor> private def d(): Double = anon$1.this.d; def <init>(): <$anon: Object> = { anon$1.super.<init>(); anon$1.this.d = 42.0; () } } } 

In the desiccated code, we see a double literal 42.0 , but no calls to any function conversions (for example, from Predef ). Thus, the conversion from Int to Double should not occur at run time, but at an earlier stage of compilation.

Section 3.5.3 of the specification says that Int weakly matches Double because of the transitivity of the weak correlation relationship <:w :

 Int <:w Long <:w Float <:w Double 

In addition, Section 6.26.1 (Value Conversion) says that the rules for numerical expansion are applicable if an expression e type T appears at a position where the expression of type pt and T weakly matches pt . In this case, we can apply the rule with

  • expression e = 42
  • expression type T = Int
  • expected type pt = Double

Thus, 42 converted to 42.0 using toDouble . Since this is a constant that can be processed at compile time, we do not see toDouble in desugged code. However, if we discard a similar program with a variable value

 val d: Double = (new scala.util.Random).nextInt(42) 

we get:

 package <empty> { object Main extends Object { def main(args: Array[String]): Unit = { new <$anon: Object>(); () }; def <init>(): Main.type = { Main.super.<init>(); () } }; final class anon$1 extends Object { private[this] val d: Double = _; <stable> <accessor> private def d(): Double = anon$1.this.d; def <init>(): <$anon: Object> = { anon$1.super.<init>(); anon$1.this.d = new scala.util.Random().nextInt(42).toDouble(); () } } } 

and toDouble as indicated.

+10
source

Source: https://habr.com/ru/post/1275771/


All Articles