必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

扩展属性允许定义在类或者kotlin文件中,有的是

2019-09-19 00:20 来源:未知

Extension 既强大方法,若写过动态语言就一定知道

世家好,小编是William李梓峰,招待参与本身的Kotlin学习之旅。
前几日是本人上学 Kotlin 的第十二天,内容是 Extensions - 扩展机制。


Kotlin的恢宏函数功效使得我们可感到依存的类加多新的函数,完成某一切实可行成效。扩张函数是静态分析的,并未有对原类加多函数或质量,对类自身并未有其余影响。增添属性允许定义在类仍旧kotlin文件中,不允许定义在函数中。


class Foo{}foo = new Foo()foo.func = funtion { //do something}之后就可以调用foo.func()函数这就是动态扩展

下文的 extension 富含七个意思,有的是指扩大机制,有的是指扩充函数和扩充属性,倘诺境遇麻烦精通的华语描述,请先看意大利语原来的书文,迎接大家改进勘误,一同发展。

欢迎关注 二师兄Kotlin
转发请注解出处 二师兄kotlin

lambda是要作为参数被传出某艺术或赋值给某变量的佚名格局的简化表现格局。

欢迎关注 二师兄Kotlin
转发请评释出处 二师兄kotlin

下面的事例是给实例扩大当然动态语言给类增添也是绝非难题的,而kotlin中能够对类进行扩展

法定文书档案:


fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){ Toast.makeText(this, message, duration).show()}

以类成员函数的点子宣示

package Bar.Fooclass Father(){ fun takeMoney(kiss:Kiss):Money{ return SelfMoney.half } fun sleep(){}}class Mather(){ //Father's extension fun Father().buyGucci():Gucci{ val kiss = giveKiss() val money = takeMoney //pay money sleep()//father.sleep() this@Mather.sleep()//mather.sleep() and this@Mather == Mather.this in java return gucci } fun wantHappy(){ val husband = Father() husband.buyGucci() } fun giveKiss():Kiss{ return kiss } fun sleep(){}}

先是表明,kotlin中也许有包的定义然则包下拔尖元素不需假如类,kotlin中的第一苍生是函数。

从上边的代码中自己想评释以下几点扩大函数的性状

  • 庞大函数是对类的扩展,对于Father来说也就是在本人内部定义了buy阿玛尼函数

  • 並且扩大函数中包含着五个援引,既有Mather的实例的援引(dispatch receiver

    )又有father实例的引用(extension receiver)所以能够间接调用三个类的函数以及质量

  • 在其他随便地点调用类的扩展都须求获得类的实例

  • 当dispatch receiver和extension receiver中有平等的函数具名,扩张方法优先调用extension receiver中的方法,除非钦命dispatch receiver

  • https://kotlinlang.org/docs/reference/extensions.html

扩展(Extensions)

前文讲过,Kotlin, 跟C#和Gosu很像,提供了方便人民群众的为类扩展函数的力量,而你并无需承接于它,或许使用设计情势来包装,比方Decorator装饰者模式. 我们接纳一种独特的宣示形式来成功这一个工作 . Kotlin 帮衬函数和性质的扩充.

this指接收者对象(receiver object)(也正是调用扩大函数时, 在"."号以前钦点的目的实例).

友元对象扩张

一旦叁个类中定义了多少个友元对象(companion object),你就足以对这么些友元对象进行函数和品质扩大。

class MyClass {
    companion object { } // will be called "Companion"
}

fun MyClass.Companion.foo() {
    // ...
}

正如友元对象的常规函数同样,只可以利用所在类的类名作为前缀举办调用:

MyClass.foo()

作用域难题

扩充方法能够直接独立在一级包中定义

package foo.barfun Baz.goo() { ... }

要在包向外调拨运输用增添方法须求import那一个艺术或然包

package com.example.usageimport foo.bar.goo // importing all extensions by name "goo"// orimport foo.bar.* // importing everything from "foo.bar"fun usage { baz.goo

当你在七个甲级包钦点义了函数签字一样的函数,举个例子

package Afun String.ok():String { return "ok"}package Bfun String.ok():String{ return "OK"}

这种情景会直接报错,假如在一级包名和贰个类中定义了长期以来的扩展函数

package Afun String.ok():String{ return "ok"}package Bclass Foo(){ fun String.ok():String{ return "OK" }}package Cfun main(s:Array<String>){ println("Ara you ok?".ok}result:ok // by Top level package

在类中以分子格局定义的扩展方法只可以在类的功能域内被调用

比如类Foo中,以及Foo的壮大函数中fun Foo.xxx(){"ok?".ok

一旦是在Foo中调用ok,成员扩充优先于拔尖扩充,成员函数也刚开始阶段于扩展函数

class C { fun foo() { println }}fun C.foo() { println("extension") }

上边这一个事例不论在别的利用调用foo函数结果都以member

Extensions - 增添机制

Kotlin, similar to C# and Gosu, provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator.
Kotlin,跟 C# 语言 以及 Gosu 语言 很像。Kotlin 提供了一种新的扩大机制,不用承继或设计形式(举例装饰器形式)。

This is done via special declarations called extensions. Kotlin supports extension functions and extension properties.
这种机制就叫 extensions (那名字一点都不绚烂)。Kotlin 帮忙函数扩大和性质扩张。(跟 javascript prototype 承袭很像的)

扩充函数(Extentions Functions)

为了声可瑞康(Karicare)个函数扩张,大家要求在函数前加三个收信人类型(receiver type)用作前缀。上边大家会为 MutableList<Int> 加多四个 swap 函数:

fun MutableList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // 'this' corresponds to the list
    this[index1] = this[index2]
    this[index2] = tmp
}

在扩张函数中的this 关键字对接待收者对象。今后大家能够在其他 MutableList<Int> 实例中使用这一个函数了:

val l = mutableListOf(1, 2, 3)
l.swap(0, 2)// 在 `swap()` 函数中 `this` 持有的值是 `l`

本来,那个函数对私行的 MutableList<T> 都是适用的,而且我们可以把它变的通用:

fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // 'this' corresponds to the list
    this[index1] = this[index2]
    this[index2] = tmp
}

我们在函数名前申明了通用项目,进而使它基本上能用别的参数。参看
泛型函数。

fun Any?.toString():String{ if(this == null) return "null" else{ return toString() }}

扩展之效能域

成都百货上千情状下我们都在甲级包下进行增添

package foo.bar
fun Baz.goo() { ... }

假使急需在高于包的界定内展开应用的话,供给举办导入(import):

package com.example.usage

import foo.bar.goo // importing all extensions by name "goo"

// or
import foo.bar.* // importing everything from "foo.bar"

fun usage(baz: Baz) {
    baz.goo()
)

扩张函数的静态性

open class C //kotlin 默认不能继承要加open修饰符class D: C()fun C.foo() = "c" //函数为第一公民当然可以对函数赋值,既返回cfun D.foo() = "d"fun printFoo { println}printFooresult:c 

下边那几个事例表明了成员函数是静态的在您表明参数类型的时候就决定了动用哪个成员函数而不是取决于你传入的实际值

Extension Functions - 函数的庞大机制

To declare an extension function, we need to prefix its name with a receiver type, i.e. the type being extended.
为了声美赞臣(Meadjohnson)个函数的恢弘,大家须要在其函数名前边写二个类别的前缀,这么些体系就是索要被扩展的类的门类。

The following adds a swap function to MutableList<Int>:
譬如说,给 MutableList<Int> 类增加八个 swap() 函数:

fun MutableList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // 'this' corresponds to the list
    this[index1] = this[index2]   // this 与 list 相对应
    this[index2] = tmp
}

The this{: .keyword } keyword inside an extension function corresponds to the receiver object (the one that is passed before the dot).
那个 this 关键字,就是意味着 MutableList 对象。因为 MutableList 是一个类,大家透过 MutableList 的目标去调用 swap(),所以 swap() 内部的 this 就是象征 MutableList 的对象。(这里直译会很难懂)

Now, we can call such a function on any MutableList<Int>:
未来吗,大家能够那样子在另外二个 MutableList 对象里面,调用那些 swap() :

val l = mutableListOf(1, 2, 3)    // new 一个 MutableList 对象
l.swap(0, 2) // 'this' inside 'swap()' will hold the value of 'l' 

Of course, this function makes sense for any MutableList<T>, and we can make it generic:
当然,这几个函数并不是接济泛型(上面的事例是写死了<Int>),大家能够那样子改动一下:

fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1] // 'this' corresponds to the list
    this[index1] = this[index2]   // this 代表对象本身
    this[index2] = tmp
}

We declare the generic type parameter before the function name for it to be available in the receiver type expression. See Generic functions.
我们在函数名的前方评释了四个泛型参数。实际情况可看 泛型函数。

庞大是被静态深入分析的

唯独,Kotlin并不实际修改它所扩张的类,给有些类定义了多个扩充函数也并未实际为那几个插入任何函数代码,仅仅是扩充了三个以此类的调用函数的门路,调用格局xx.extentionsFunc。

亟待重申的是扩充函数是静态分发的,比如,它们并非接受者类型的虚拟方法。那意味扩大函数的调用是由发起函数调用的表达式的门类决定的,并不是在运作时动态得到的表达式的品种决定。比方
举例:

open class C

class D: C()

fun C.foo() = "c"

fun D.foo() = "d"

fun printFoo(c: C) {
    println(c.foo())
}
printFoo(D())

事例中输出的结果是c。扩充函数被调用时,传入的参数是c, 即类C。

假使四个类具备三个分子函数,可是又定义了三个那些类的庞大函数和它的分子函数名字一模二样,参数也一律,此时只举行成员函数

举例:

class C {
    fun foo() { println("member") }
}

fun C.foo() { println("extension") }

诸如我们调用 类C的自由实例cc.foo() 函数 , 只会打字与印刷 “member”, 而不是“extension”.

与上述任何境况亦然,名字一样只是函数签字不一样有的时候候,扩充函数专业全盘健康,举个例子:

class C {
    fun foo() { println("member") }
}

fun C.foo(i: Int) { println("extension") }

调用 C().foo(1) 时将会输出“extension”.

1.扩展(extensions)

扬言扩充作为成员函数

在一个类的里边,你可认为其他三个类申明扩张。而在扩展内部,则存在八个隐式的收信人---对象足以采访成员而不需出示钦点归属类名。在宣称扩充所在的类实例叫做分发接收者(dispatch receiver),而增添函数的收信人类的实例叫做扩张接收者( extension receiver)。

class D {
    fun bar() { ... }
    }

    class C {
        fun baz() { ... }
        fun D.foo() {
            bar() // calls D.bar
            baz() // calls C.baz
    }

    fun caller(d: D) {
        d.foo() // call the extension function
    }
}

万一 分发接收者和增添接收者的函数名存在争论,优先接纳扩大接收者的函数。要是要援用分发接收者(dispatch receiver)的成员,请使用qualified this syntax。

class C {
    fun D.foo() {
        toString() // calls D.toString()
        this@C.toString() // calls C.toString()
}

将扩展函数注明时,能够运用open来声称, 何况能够在子类中重写。那就表示扩展函数对于分发接收者来说是虚函数,而对此扩张接收者来讲是静态的。

open class D {
}

class D1 : D() {
}

open class C {
    open fun D.foo() {
        println("D.foo in C")
    }

    open fun D1.foo() {
        println("D1.foo in C")
    }

    fun caller(d: D) {
        d.foo() // call the extension function
    }
}

class C1 : C() {
    override fun D.foo() {
        println("D.foo in C1")
    }

    override fun D1.foo() {
        println("D1.foo in C1")
    }
}


C().caller(D()) // prints "D.foo in C"
C1().caller(D()) // prints "D.foo in C1" - dispatch receiver is resolved virtually
C().caller(D1()) // prints "D.foo in C" - extension receiver is resolved statically

对友元扩张

kotlin中尚无static关键字也并未有实际的静态概念,假若想像java那样调用静态方法和静态成员能够用友元

class My{ companion object(){ val I = 1 fun getNum():Int{ return I } }}fun main(args:Array<String>){ val num = My.getNum() val i = My.I println}result:true

友元也得以扩充扩充只要像上边这样写

class MyClass { companion object { } // will be called "Companion"}fun MyClass.Companion.foo() { // ...}

Extensions are resolved statically - 静态管理增添机制

Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
扩展机制并非真正改换了被扩张的类。在概念贰个恢弘函数的时候,你不能增加新的分子到类里面去,只好够在类的变量上绑定贰个新的函数。(类似 Java 静态方法,但这些是能够动态地抬高静态方法,静态方法由类去调用)

We would like to emphasize that extension functions are dispatched statically, i.e. they are not virtual by receiver type.
咱俩重申的是,扩张函数是静态调用的,即,它们并无法依据项目虚构化。(这里有一些绕口,就是未有面向对象的多态性,不援救多态调用)

This means that the extension function being called is determined by the type of the expression on which the function is invoked, not by the type of the result of evaluating that expression at runtime. For example:
野趣正是说,扩大函数的调用是由当时编写制定的档期的顺序全部决定的,并非由当时运作的体系决定的(便是不可知多态调用,不能够用父类的援用调用子类的主意),比方:

open class C       // open 让 C 类可以被继承

class D: C()        // D 类继承了 C 类

fun C.foo() = "c"      // 声明 C 类的扩展函数 foo()

fun D.foo() = "d"     // 声明 D 类的扩展函数 foo()

fun printFoo(c: C) {     // 传入 C 类对象
    println(c.foo())        // 打印 C 类的 foo() 返回的字符串
}

printFoo(D())   // 传入 D 类对象,打印结果是 "c",而不是 “d”

This example will print "c", because the extension function being called depends only on the declared type of the parameter c, which is the C class.
以此例子实施后会打字与印刷 “c”,因为扩充函数的调用信赖于申明的花色,即 C 类。

If a class has a member function, and an extension function is defined which has the same receiver type, the same name and is applicable to given arguments, the member always wins.
只要三个类有个成员函数(方法),并且恰恰有个增加函数跟其同名,而且它们俩的参数依然一样的,那么此时,分子函数(方法)总会赢。(成员函数蛮拼的,爱拼才会赢嘛)

For example:

class C {
    fun foo() { println("member") }
}

fun C.foo() { println("extension") }

If we call c.foo() of any c of type C, it will print "member", not "extension".
假诺大家调用 c.foo() ,就能够打字与印刷 “member”,并非 “extension”。

However, it's perfectly OK for extension functions to overload member functions which have the same name but a different signature:
纵然那样,只要扩大函数有不相同的形参,即使同名,也能百分之百地调用到啊:

class C {
    fun foo() { println("member") }
}

fun C.foo(i: Int) { println("extension") }  // 多了个 int i 参数

The call to C().foo(1) will print "extension".
那标准就能够调取扩充函数了,打字与印刷出 “extension”。

空切收者

小心扩充能够采取空切收者类型进行定义。那样的扩充使得,即便是一个空对象依旧能够调用该扩大,然后在扩张的里边实行this == null 的论断。这样您就足以在 Kotlin 中大肆调用 toString() 方法而不实行空指针检查:空指针检查延后到扩充函数中做到。

fun Any?.toString(): String {
    if (this == null) return "null"
    // after the null check, 'this' is autocast to a non-null type, so the toString()
below
    // resolves to the member function of the Any class
    return toString()
}

在不修改原类的情状下,Kotlin能给贰个类扩张新成效,没有须要继承该类,也不用别的设计形式,Kotlin帮助扩张函数和扩展属性!

动机

在Java中,大家习贯于接纳类名叫*UtilsFileUtils , StringUtils等等。著名的java.util.Collections也属于这一类。不过这几个类有一点点用起来令人感到很不爽的地方:

// Java
Collections.swap(list, Collections.binarySearch(list, Collections.max(otherList)),
Collections.max(list))

要么大家得以静态导入,产生那样写:

// Java
swap(list, binarySearch(list, max(otherList)), max(list))

尽管如此那样写会略带好有的,可是大家却心有余而力不足从IDE的无敌的代码补全功能中收获赞助。若是大家能够那样写会不会更加好有的啊:

// Java
list.swap(list.binarySearch(otherList.max()), list.max())

不过大家总不可能落实List的具有函数吧,那一年Kotlin的恢宏作用就足以对大家发出协助了。


本节完

强大属性

可以给率性类扩展一个属性

val <T> List<T>.lastIndex: Int get() = size - 1

可是扩大的习性实际不是实际上在类里插入变量,所以并未有好的法子给它分配实际的积累空间,所以扩充成员无法被赋值只能重写他的get方法,其实那就和三个函数同样了

Nullable Receiver - 可为空的接收器

Note that extensions can be defined with a nullable receiver type. Such extensions can be called on an object variable even if its value is null, and can check for this == null inside the body.
扩张机制能够被贰个可为空的接收器类型所定义。这几个扩展机制得以在指标变量上所调用,尽管该对象是空的,并且,还足以在扩大函数内部用 this == null 来决断该目的是还是不是正是空的。(太屌了,又是三个杀手级性情,Kotlin 的恢宏机制已经超越 jQuery 的 extend() 函数 )

This is what allows you to call toString() in Kotlin without checking for null: the check happens inside the extension function.
在那一个事例中,你能够一直调用增添函数 toString() 。因为扩充函数允许你的对象便是为空也得以一贯调取,那样子就不轻巧报空指针格外啦。用扩大函数来保证成员函数,那招厉害了自己的哥。

fun Any?.toString(): String {
    if (this == null) return "null"
    // after the null check, 
    // 'this' is autocast to a non-null type,
    // so the toString() below
    // resolves to the member function of the Any class
    return toString()   // 这里调用真正的成员函数
}

恢宏属性

类似扩大函数,Kotlin同样帮助扩张属性:

val <T> List<T>.lastIndex: Int
    get() = size - 1

只顾,扩充函数并未有向类中插入函数 , 扩展属性在类中也并不曾扶助字段(backing field)。那正是为啥开首化程序(initializers)分裂意扩张属性。 唯有在体现提供getters/setters后技巧够定义扩大属性,举个例子:

val Foo.bar = 1 // error: initializers are not allowed for extension properties

接下去会呈报友元对象扩充以及扩张的作用域。
前文讲过,Kotlin, 跟C#和Gosu很像,提供了便利的为类扩大函数的技艺,而你并无需承继于它,或许采取设计形式来包装,比如Decorator装饰者模式. 大家选拔一种特有的申明方式来产生这么些专业 . Kotlin 协理函数和质量的扩张.

何以要运用扩大:在Java中,有比非常多工具类如java.util.Collections,使用很麻烦:

空类型接收器

kotlin 中暗中认可的变量是 not null 的假如这几个函数恐怕为null就要在项近些日子面加?例如String?就象征这些字符串有不小可能率是null,而大家也足以给那类别型加扩充,那么我们管理null判定的法子就可以写成这样的扩充情势,那样您就足以放心的调用toString()而不用判定是或不是为空

fun Any?.toString(): String { if (this == null) return "null" // after the null check, 'this' is autocast to a non-null type, so the toString() below // resolves to the member function of the Any class return toString()}

Extension Properties - 属性的庞大机制

Similarly to functions, Kotlin supports extension properties:
跟函数类似,Kotlin 援救扩大属性:

val <T> List<T>.lastIndex: Int
    get() = size - 1         // 属性有访问器 setter getter

Note that, since extensions do not actually insert members into classes, there's no efficient way for an extension property to have a backing field. This is why initializers are not allowed for extension properties. Their behavior can only be defined by explicitly providing getters/setters.
要知道,扩充机制实际不是是给类增多成员的,所以扩展属性未有备用属性。那也是为啥 开端化代码中不容许有扩大属性,因为起首化代码中,暗许的 setter 要给备用属性赋值。由此,扩张属性只好显式地宣称 setter 或 getter,何况在访问器中无法访问备用属性(备用字段)。

Example:

val Foo.bar = 1 // error: initializers are not allowed for extension properties

庞大函数(Extentions)的“静态施行”

而是,Kotlin并不实际修改它所扩张的类,给有些类定义了二个扩张函数也并从未实际为那几个插入任何函数代码,仅仅是加多了二个以此类的调用函数的路子,调用格局xx.extentionsFunc。
亟待重申的是扩张函数只好“在调用处静态的办事”, 意思是调用处传入的参数是哪个人就是何人,不扶助多态。

举例:

open class C

class D: C()

fun C.foo() = "c"

fun D.foo() = "d"

fun printFoo(c: C) {
    println(c.foo())
}
printFoo(D())

事例中输出的结果是c。扩充函数被调用时,传入的参数是c, 即类C。

一经贰个类具备二个分子函数,不过又定义了贰个以此类的恢弘函数和它的积极分子函数名字一模一样,参数也完全一样,此时只举行分子函数

举例:

class C {
    fun foo() { println("member") }
}

fun C.foo() { println("extension") }

举例大家调用 类C的轻便实例cc.foo() 函数 , 只会打字与印刷 “member”, 实际不是“extension”.

与上述任何意况一致,名字同样只是函数具名区别有时候,增加函数职业完全符合规律,比如:

class C {
    fun foo() { println("member") }
}

fun C.foo(i: Int) { println("extension") }

调用 C().foo(1) 时将会输出“extension”.

// JavaCollections.swap(list, Collections.binarySearch(list, Collections.max(otherList)), Collections.max

Extension的使用场景

  • 可以改变部分原生的class 而不用写一个Utils类,比方给String加二个格式化日期扩充

    fun String().toDate(format:String = "yyyy-MM-dd HH:mm:ss") :String{ val sdf = SimpleDateFormat val date = sdf.parse return date.toString()}fun main(args:Array<String>){ println("UTC format Date".toDate//2017-11-11 11:11:11}
    

  • 能够写一些超越二分之一分拣都通用的routine

    //例如:fun doSomething(){ try{ //doing }catch(e:Exception){ //error }}//这样的代码在java中有大把而且很多人其实catch了之后也不会做什么特殊的处理当代码中到处充斥这种结构甚至嵌套好几层其实无形增加的阅读的难度和维护的难度//extension wayfun <T> T.dowithTry->Unit){ try{ work }catch(e:Exception){ //print error etc. }}fun <T:Closeable> T.dowithTry->Unit){ try{ work }catch(e:Exception){ //print error etc. }finally{ this.close() }}//那么你只要这么调用,甚至脸close都帮你做了fun main(arg:Array<String>){ val output = File().outputStream() output.dowithTry{ it -> it.read() .... }}
    
  • 贯彻部分函数式编制程序的法力

Companion Object Extensions - 伴随对象的扩充仲景制

此处猛然冒出了伴随对象,从前也出现过,然而由于指标表明式在后边才会标准介绍,这里能够先留个心眼,大约看懂就行了。伴随对象正是在类的评释体内部写多少个无名氏或非佚名的静态内部类,伴随对象的不二法门能够被表面类用静态的不二等秘书诀来调用。

If a class has a companion object defined, you can also define extension functions and properties for the companion object:
万一二个类有陪同对象,你就足以给它定义扩张函数和增加属性:

class MyClass {
    companion object { }  // will be called "Companion"
}

fun MyClass.Companion.foo() {   // Companion 是当伴随对象的默认名字
    // ...
}

Just like regular members of the companion object, they can be called using only the class name as the qualifier:
就如普通的陪伴对象成员平等,它们也得以用外表类来直接访谈:

MyClass.foo()

空切收者

细心扩展能够应用空中接力收类型,如此扩大就能够被一个就算值为null的变量所调用,而且能够在扩大函数体中实施行检查查this == null。那正是为啥在Kotlin中您不用检查是或不是为null就可以调用toString: 检查发生在庞大函数中。

fun Any?.toString(): String {
    if (this == null) return "null"
    // after the null check, 'this' is autocast to a non-null type, so the toString()
below
    // resolves to the member function of the Any class
    return toString()
}

静态导入Collections类,简化写法:

结语

扩大是个很遗闻物发挥想想力能写出广大晋升功用和阅读性扩充函数

Scope of Extensions - 扩展机制的域

Most of the time we define extensions on the top level, i.e. directly under packages:
绝大多数时候,大家都是在顶层概念扩张机制(顶层即该文件的全局层),即直接在包下定义:

package foo.bar

fun Baz.goo() { ... }    // Barz 类的扩展函数 goo()

To use such an extension outside its declaring package, we need to import it at the call site:
为了在包的表面调用那几个扩张机制,咱们须求 import 一下:

package com.example.usage

import foo.bar.goo // importing all extensions by name "goo"
                   // or
import foo.bar.*   // importing everything from "foo.bar"

fun usage(baz: Baz) {
    baz.goo()
}

See Imports for more information.
详见请看 引入

推而广之属性

周围增添函数,Kotlin一样补助增添属性:

val <T> List<T>.lastIndex: Int
    get() = size - 1

瞩目,扩充函数并未有向类中插入函数 , 增加属性在类中也并从未扶助字段(backing field)。这正是为啥伊始化程序(initializers)不允许扩张属性。 唯有在体现提供getters/setters后才足以定义扩大属性,比如:

val Foo.bar = 1 // error: initializers are not allowed for extension properties

接下去会陈诉友元对象扩充以及扩充的功能域。

// Javaswap(list, binarySearch(list, max(otherList)), max

Declaring Extensions as Members - 声明扩充为成员

Inside a class, you can declare extensions for another class. Inside such an extension, there are multiple implicit receivers - objects members of which can be accessed without a qualifier.

静态导入使用依然很费劲,如若能给list类加多扩张函数就好了:

TAG标签:
版权声明:本文由必威发布于必威-编程,转载请注明出处:扩展属性允许定义在类或者kotlin文件中,有的是