This section mainly introduces the principles of top-level functions and properties, extended functions and properties, understands the differences between them and Java, and proposes the concept of local functions
1. Top level functions and properties
Top level functions do not belong to any class, which can be understood as Java static functions
//In the file Join.kt package strings fun joinToString(...): String { ... } const val UNIX_LINE_SEPARATOR = "\n"
Equivalent to
package strings; public class JoinKt { public static String joinToString(...) { ... } public static final String UNIX_LINE_SEPARATOR = "\n"; }
2. Extension function
//In the extendiontextview.kt file //Extended function definition fun TextView.isBold() = this.apply { paint.isFakeBoldText = true } //Extension function call activity.find<TextView>(R.id.course_comment_tv_score).isBold()
Equivalent to the following Java code:
public final class ExtendsionTextViewKt {//This class name is the top file name plus "Kt" suffix. The last blog has a detailed introduction to this knowledge public static final TextView isBold(@NotNull TextView $receiver) {//The extension isBold corresponds to a static function in Java, and passes in a receiver type object as a parameter Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); $receiver.getPaint().setFakeBoldText(true);//Setting thickening return $receiver;//Finally, the receiver object itself is returned, so that we can use this instead of the receiver object or not write directly in Kotlin. } }
In fact, it's a static function. The static function parameter is an object of receiver type. With this object, you can access everything in this object. So it's equivalent to extension. How is the extension property implemented? You can think about it first, then look at the following.
3. Extended properties
//In the extendiontextview.kt file //Extended attribute definition var TextView.isBolder: Boolean get() {//You must define the get() method, because you can't add fields to existing objects, and naturally there is no default get() implementation return this.paint.isFakeBoldText } set(value) { this.paint.isFakeBoldText = true } //Extended property call activity.find<TextView>(R.id.course_comment_tv_score).isBolder = true
Equivalent to the following Java code:
public final class ExtendsionTextViewKt { //The get() method generates a static function and passes in a receiver type object as a parameter public static final boolean isBolder(@NotNull TextView $receiver) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); return $receiver.getPaint().isFakeBoldText(); } //The set() method generates a static function and passes in a receiver type object as a parameter and a parameter that needs to be set public static final void setBolder(@NotNull TextView $receiver, boolean value) { Intrinsics.checkParameterIsNotNull($receiver, "$receiver"); $receiver.getPaint().setFakeBoldText(true); } }
In fact, we added the receiver type object in the get and set methods. With this object, we can access everything in this object
But the extension functions and properties are static, so they cannot be overridden
4. Local function
class User(val id: Int, val name: String, val address: String) fun saveUser(user: User) { if (user.name.isEmpty()) { throw IllegalArgumentException("User name is empty and cannot be saved") } if (user.address.isEmpty()) { throw IllegalArgumentException("User address is empty and cannot be saved") } //Save user }
Make the code of the inspection field into a local function of verification
fun saveUser(user: User) { fun validate(value: String, fieldName: String) { if (value.isEmpty()) { throw IllegalArgumentException("user ${user.fieldName} Cannot save if it is empty") //user object that local function can access external function } } validate(user.name, "name") validate( user.address, "address") //Save user }
Of course, you can also use this local function directly into the extension function
fun User.validateBeforeSave() { fun validate(value: String, fieldName: String) { if (value.isEmpty()) { throw IllegalArgumentException("user $fieldName Cannot save if it is empty") } } validate(name, "name") validate(address, "address") } fun saveUser(user: User) { user.validateBeforeSave() //Save user }