Scala-Implicit conversions

Source: Internet
Author: User


To put it simply, implicit conversions are: When the Scala compiler does type matching, if no suitable candidate is found, implicit conversions provides another way to tell the compiler how to convert the current type to the expected type. This article source: prohibited any form of reprint, or will entrust CSDN official maintenance rights!

There are four common usage scenarios for implicit conversions:

    1. Convert a type to the expected type
    2. Type enhancement and expansion
    3. Simulate the new syntax
    4. Type class

Implicit conversion has both old and new definitions, the old definition method is the "Implict def" form, which was written before the Scala 2.10 version, after Scala version 2.10, Scala introduced the "implicit class" to replace the old implicit conversion syntax, because the "implicit class" is a more secure way, and its scope is clearer and more manageable for the type being converted.

We then use examples to understand how these two implicit conversions are written. As mentioned earlier, the most basic usage scenario for implicit conversions is to convert a type to the expected type, so the following example demonstrates this in the simplest scenario: implicitly converting a variable of type string to an int type:

Implicit conversion of "implict def" form
 PackageCom.github.scala.myimplicit/** * A demo about Scala implicit type conversion. * @author Laurence Geng * * Object implicitdefdemo {     Object myimplicittypeconversion {ImplicitdefStrtoint (str:string) = Str.toint}defMain (args:array[string]) {//compile error!        //val max = Math.max ("1", 2);        ImportMyimplicittypeconversion.strtointValmax = Math.max ("1",2); println (max)}}
Implicit conversions in the form of "implicit classes"
 PackageCom.github.scala.myimplicit/** * A demo about Scala implicit type conversion. * @author Laurence Geng * * Object implicitclassdemo {Implicit class myimplicittypeconversion(val str:string){         defStrtoint = Str.toint}defMain (args:array[string]) {//compile error!        //val max = Math.max ("1", 2);        ImportCom.github.scala.myimplicit.implicitdefdemo.myimplicittypeconversion._Valmax = Math.max ("1",2); println (max)}}

There are several limitations to implicit classes:

    1. They must be defined inside of another trait/class/object.

    2. They may only take one non-implicit argument in their constructor.

    3. There may is not a method, member or object in scope with the same name as the implicit class.
      Note:this means an implicit class cannot is a case class.

The implicit class and the old implicit conversion syntax (implicit def) are slightly different, the implicit class works by: The main constructor of the implicit class can have only one parameter (more than two does not error, but this implicit class is never used by the compiler as an implicit class in implicit conversions), And the type of this parameter is the target type that will be converted. Semantically This is natural: this implicit conversion class wraps the target type, and all methods of the implicit class are automatically "attached" to the target type.

Application scenarios converted to expected types

For this kind of usage scene is actually not very rare, the actual meaning is not that big. The preceding code is an example of this scenario.

Type enhancement and expansion

What really makes the implicit conversion shine is "type enhancement." Examples of this are very numerous.

Case one: Arrayops type enhancements to array

A typical case is: Scala's implicit conversion to an array object. We know that Scala declares two implicit conversions for array types through Predef: One is implicit conversions to arrayops and the other is implicit conversions to Wrappedarray. As an example, it adds a lot of operations to the array object, which is a typical case of enhancing a class by implicitly converting it! The following is a description of this technical detail in the Scala API documentation:

Two implicit conversions exist in scala.Predef that are frequently applied to arrays: a conversion to scala.collection.mutable.ArrayOps (shown on line 4 of the example above) and a conversion to scala.collection.mutable.WrappedArray (a subtype of scala.collection.Seq). Both types make available many of the standard operations found in the Scala collections API. The conversion to ArrayOps is temporary, as all operations defined on ArrayOps return an Array, while the conversion to WrappedArray is permanent as all operations return a WrappedArray.
Case two: Pairrddfunctions type enhancements to RDD in spark

If you look at the RDD in Spark and its subclasses are not Groupbykey, Reducebykey, and join-based operations of Key-value tuples, but when you use the RDD, these operations are real, It is the implicit conversion of spark that transforms an rdd into a pairrddfunctions, and this action happens:

The implicit conversion from RDD to Pairrddfunctions is first declared in the accompanying object of the RDD:

Then import all of the RDD in the Sparkcontext, making the implicit conversion effective.

Simulate the new syntax

This is also a very cool application scenario. A typical application scenario is the symbol, which is used to create the Key-value tuple in map, which is the product of an implicit conversion. Not the syntax of Scala itself, but a method of type Arrowassoc. This type is defined in the package Scala.predef object. Scala.predef is automatically introduced to the current scope, in which an implicit transformation from the type any to the ARROWASSOC is defined. So when using "one", 1, the compiler automatically inserts the conversion from 1 to Arrowasso c.

Type class

The type class is a very flexible design pattern that separates the definition and behavior of a type, making it very convenient to extend class behavior. Or if we want to create a feature that spans types (that is, functional implementations are independent of the type), then such "functionality" is not appropriate and should not evolve on the hierarchy of the main type, which is a great place to use type classes. Because the type class is a relatively independent syntax, although its implementation requires the use of a type class, in this article we do not intend to go into detail here, but in the following article, in order not to lose focus.

Implicit parsing of search scopes

The rules in this section are somewhat complex, as described in the Scala in Depth, the top-level search logic is:

    • Look under the current scope. There are two cases in which the implicit element of the declaration is displayed in the current scope, and the other implicit element is imported through import.
    • If the first method is not found, the compiler continues to look in the implicit scope of the implicit parameter type.

What's really complicated is what is called an implicit scope of a type? The implicit scope of a type refers to all associated objects of the type associated with that type.

OK, what do you mean by "types associated with a type"? Defined as follows:

    • If T is defined like this: T with a with B with C, then the associated object of a, B, C is the search area of T.
    • If T is a type parameter, then both the parameter type and the underlying type are the search parts of T. For example, the type list[foo],list and Foo are search areas
    • If T is a singleton type p.t, then both P and T are search areas
    • If T is a type injection p#t, then both P and T are search areas.

Why take the implicit argument out and put it in the end because the implicit argument is very different from the implicit type conversion we talked about earlier, although it involves the keyword implict, but it does something else. The implied argument is somewhat similar to the default parameter, and if a parameter is not supplied when the method is called, the compiler will look for a qualified implicit object in the current scope to be passed in as a parameter, unlike the default parameter, where the value of the implicit parameter can be specified in the context of the method call. This is where implicit parameters are more flexible.

object ImplicitParamDemo {    object Greeter{        def greet(name:String)(implicit prompt: String) {            println("Welcome, "". The System is ready.")            println(prompt)        }    }    def main(args: Array[String]) {        val">"        Greeter.greet("admin")    }}

Scala-Implicit conversions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.