Scala equivalent of C#’s extension methods?

前端 未结 5 1765
傲寒
傲寒 2020-12-07 12:09

In C# you can write:

using System.Numerics;
namespace ExtensionTest {
public static class MyExtensions {
    public static BigInteger Square(this BigInteger          


        
相关标签:
5条回答
  • 2020-12-07 12:35

    In Scala we use the so-called (by the inventor of the language) Pimp My Library pattern, which is much discussed and pretty easy to find on the Web, if you use a string (not keyword) search.

    0 讨论(0)
  • 2020-12-07 12:41

    This would be the code after Daniel's comment.

    object MyExtensions {
        class RichInt( i: Int ) {
            def square = i * i
        }
        implicit def richInt( i: Int ) = new RichInt( i )
    
        def main( args: Array[String] ) {
            println("The square of 2 is: " + 2.square )
        }
    }
    
    0 讨论(0)
  • 2020-12-07 12:43

    Scala 3 now has extension methods. Functionally it seems similar as expected to C# and Kotlin.

    https://dotty.epfl.ch/docs/reference/contextual/extension-methods.html
    https://github.com/scala/scala
    https://github.com/lampepfl/dotty

    A recent (as of this post) pull shows the syntax being simplified. Stable version as of this post is still 2.x. But there is a 3.xRC, and I noticed Jetbrains already supports it in Idea, partially I assume.

    0 讨论(0)
  • 2020-12-07 12:48

    The Pimp My Library pattern is the analogous construction:

    object MyExtensions {
      implicit def richInt(i: Int) = new {
        def square = i * i
      }
    }
    
    
    object App extends Application {
      import MyExtensions._
    
      val two = 2
      println("The square of 2 is " + two.square)
    
    }
    

    Per @Daniel Spiewak's comments, this will avoid reflection on method invocation, aiding performance:

    object MyExtensions {
      class RichInt(i: Int) {
        def square = i * i
      }
      implicit def richInt(i: Int) = new RichInt(i)
    }
    
    0 讨论(0)
  • 2020-12-07 12:53

    Since version 2.10 of Scala, it is possible to make an entire class eligible for implicit conversion

    implicit class RichInt(i: Int) {
      def square = i * i
    }
    

    In addition, it is possible to avoid creating an instance of the extension type by having it extend AnyVal

    implicit class RichInt(val i: Int) extends AnyVal {
      def square = i * i
    }
    

    For more information on implicit classes and AnyVal, limitations and quirks, consult the official documentation:

    • http://docs.scala-lang.org/overviews/core/implicit-classes.html
    • http://docs.scala-lang.org/overviews/core/value-classes.html
    0 讨论(0)
提交回复
热议问题