I was wondering what kotlin's reserved word, infix, was, so I looked up the definition and how to make it.
--Somehow fix --Example of standard library: "to" --Define infix functions --Call the defined infix function from Kotlin --Call the defined infix function from Java --Disassemble the infix function --Reference
In the first place. What is infix? I don't know English words (laughs) When I run Google Translate, it returns "inside". I noticed here that this is one of the fixes. There are other fixes that I often use. prefix、suffix。 Literally in the middle, it is a function of Kotlin that can define a function that puts an infix function between objects and values and processes with two objects and values sandwiched between them as arguments.
The standard library infix function to
is called as follows to create a Pair
instance.
Pair.kt
val pair: Pair<String, String> = "key" to "value"
The method is defined as an extension function as shown below.
Standard.kt
/**
* Creates a tuple of type [Pair] from this and [that].
*
* This can be useful for creating [Map] literals with less noise, for example:
* @sample samples.collections.Maps.Instantiation.mapFromPairs
*/
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
Reference: Tuples.kt
Then, I would like to make my own infix function.
Imagine a case where you often encounter "refilling values into instances of similar objects that have similar objects".
Here, create a function that attaches a history sequence to the value of the Customer
class to create an instance of the CustomerHistory
class, and returns a Pair
instance that includes those instances in the generics.
First, define the data class that will be the result of input and synthesis.
Data.kt
data class Customer (
var id: String,
var name: String
)
data class CustomerHistory (
var id: String,
var name: String,
var seq: Int
)
Define the infix function that creates a CustomerHistory
instance with a sequence from the original Customer
as follows.
Infix.kt
/**
*The receiver is treated as this inside the extension function. The sequence is received as a function argument.
*/
infix fun Customer.mapToHistory(seq: Int): Pair<Customer, CustomerHistory> = Pair(
this,
CustomerHistory(
this.id,
this.name,
seq
)
)
Now you are ready. Now, let's call the infix function defined from Kotlin code and Java code.
Call the self-made infix function defined above.
Caller.kt
//Former story.
val customer: Customer = Customer("00001", "Eron Musk")
//Returns the original material and the Pair of the history object with a sequence.
val pair: Pair<Customer, CustomerHistory> = customer mapToHistory 2
The defined function wasn't good as an example, so it's hard to understand, but you can get the result by putting the defined function between objects and values.
Due to Kotlin's interoperability, it can also be called from Java. If you try a snippet of a similar call in Java
Caller.java
/**
*The return value is kotlin included in Kotlin's library..Import and define Pair.
*/
public static void printHistory(Customer customer) {
Pair<Customer, CustomerHistory> customerHistory = InfixKt.mapToHistory(customer, 2);
}
After all, I was expecting it, but from Java's point of view, the infix function is a static method.
The defined Kotlin file was compiled with kotlinc
.
I can almost imagine the instruction procedure by looking at the call from Java, but I'm curious. So, let's disassemble the compiled Kotlin file (class file).
mac:classes user$ javap InfixKt.class
Compiled from "Infix.kt"
public final class InfixKt {
public static final kotlin.Pair<Customer, CustomerHistory> mapToHistory(Customer, int);
}
It was just as I expected ... Kotlin files with no classes or multiple classes are named \
2020-07-02: Addendum It is a static method because the function I made is an extension function.
Add an option to javap
and try to output a little more detailed information.
mac:classes user$ javap -c -l -p InfixKt.class
Compiled from "Infix.kt"
public final class InfixKt {
public static final kotlin.Pair<Customer, CustomerHistory> mapToHistory(Customer, int);
Code:
0: aload_0
1: ldc #10 // String $this$mapToHistory
3: invokestatic #16 // Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull:(Ljava/lang/Object;Ljava/lang/String;)V
6: new #18 // class kotlin/Pair
9: dup
10: aload_0
11: new #20 // class CustomerHistory
14: dup
15: aload_0
16: invokevirtual #26 // Method Customer.getId:()Ljava/lang/String;
19: aload_0
20: invokevirtual #29 // Method Customer.getName:()Ljava/lang/String;
23: iload_1
24: invokespecial #33 // Method CustomerHistory."<init>":(Ljava/lang/String;Ljava/lang/String;I)V
27: invokespecial #36 // Method kotlin/Pair."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
30: areturn
LineNumberTable:
line 12: 6
line 13: 10
line 14: 11
line 15: 15
line 16: 19
line 17: 23
line 14: 24
line 12: 27
line 19: 30
LocalVariableTable:
Start Length Slot Name Signature
0 31 0 $this$mapToHistory LCustomer;
0 31 1 seq I
}
After all, it seems that it is a Java opcode that I knew even after it was compiled.
――Infix is a word that refers to infix and is like being placed between prefixes / suffixes. --The infix function is a function that performs processing by placing it between values and objects. --From Java's point of view, it looks like syntactic sugar for static methods.
Books Kotlin in Action
website [Internal notation-Kotlin reference](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/functions.html#%E4%B8%AD%E7%BD%AE%E8% A8% 98% E6% B3% 95)