标签: kotlin-extension

我们应该避免在Kotlin中命名与现有类相同的函数吗?为什么?

Kotlin允许命名一个与现有类相同的函数,例如HashSet初始化函数可以像这样实现:

fun <T> HashSet(n : Int, fn: (Int) -> T) = HashSet<T>(n).apply {
    repeat(n) {
        add(fn(it))
    }
}
Run Code Online (Sandbox Code Playgroud)

使用时,它看起来像一个普通的HashSet构造函数:

var real = HashSet<String>()
var fake = HashSet(5) { "Element $it" }
Run Code Online (Sandbox Code Playgroud)

这应该避免或鼓励,为什么?

kotlin kotlin-extension

8
推荐指数
1
解决办法
707
查看次数

Kotlin延伸冲突

如果我有一个jar,在类路径上,我已经创建了一个扩展函数,说出String类为了参数的缘故,我在String上有另一个具有相同扩展函​​数的jar,Kotlin如何解析这两个?

我假设如果两个函数都在同一个包中定义,那么会发生冲突吗?

但如果不同的包,我怎么能区分这两个扩展?

java kotlin kotlin-extension

8
推荐指数
2
解决办法
504
查看次数

受保护的成员在扩展功能中无法访问?

Kotlin具有几个可见性修饰符扩展功能.文件说明了这一点Extensions are resolved statically.但这对扩展函数中类成员的可见性意味着什么呢?

让我们考虑以下人为的例子:

class A { protected val a = "Foo" }
fun A.ext() { print(a) } //Raises: Cannot access 'a': it is 'protected' in 'A'

class B { val b = "Bar" }
fun B.ext() { print(b) } //Compiles successful
Run Code Online (Sandbox Code Playgroud)

代码不会编译.在扩展类时似乎无法访问受保护的成员.

因此,解决静态意味着扩展函数是在Java中具有类似内容的语法糖:

public static void ext(A receiver){ System.out.print(receiver.a); }
Run Code Online (Sandbox Code Playgroud)

这可以解释为什么受保护的成员无法访问.另一方面,可以this在扩展函数中使用(甚至省略).

那么扩展功能的确切范围是什么?

kotlin kotlin-extension

7
推荐指数
1
解决办法
1035
查看次数

Kotlin内联扩展属性

我知道内联关键字的意思是避免调用功能的调用开销。但是我不知道扩展属性可以用于什么内联?

假设我们有两个名为foo的扩展属性,另一个带有名为bar的内联属性

val Any.foo : Long
    get() = Date().time

inline val Any.bar : Long
    get() = Date().time
Run Code Online (Sandbox Code Playgroud)

执行其中的任何一个,我们将期望的输出,即当前时间。

该文件的字节码如下:

val Any.foo : Long
    get() = Date().time

inline val Any.bar : Long
    get() = Date().time
Run Code Online (Sandbox Code Playgroud)

我们可以看到两者相似,但仅在以下几行不同:

foo提取:

    LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
Run Code Online (Sandbox Code Playgroud)

酒吧摘录:

    LOCALVARIABLE $receiver Ljava/lang/Object; L0 L2 0
    LOCALVARIABLE $i$f$getBar I L0 L2 1
    MAXSTACK = 2
    MAXLOCALS = 2
Run Code Online (Sandbox Code Playgroud)

我真的不明白这里发生了什么。有人可以指点我看一下它的行为,或java中的等效行为,或对此的一些用法吗?

编辑

给定编译器将替换内联属性的内容,可以方便地内联每个没有繁重操作的扩展属性。

谢谢

inline kotlin kotlin-extension jvm-bytecode

7
推荐指数
1
解决办法
1249
查看次数

如何使用Android中的Kotlin从NavigationView的headerLayout中指定的布局访问视图

我想访问包含在NavigationView的headerLayout中的TextView.是否可以使用Kotlin android扩展程序访问该视图?我使用了这个方法,但TextView(此处为txtName)始终为null.

这是我的activity_main.xml

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="end"
    android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_splash"
    app:menu="@menu/activity_splash_drawer" />
Run Code Online (Sandbox Code Playgroud)

nav_header_splash.xml

<TextView
    android:id="@+id/txtName"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/txt1"
    android:layout_below="@+id/imageView"
    android:text="@string/name"
    android:textSize="18sp"
    android:textColor="@color/white" />
Run Code Online (Sandbox Code Playgroud)

MainActivity.kt 我已导入

import kotlinx.android.synthetic.main.nav_header_splash.*
Run Code Online (Sandbox Code Playgroud)

onCreate()Activity类我设置文本就好

txtName.text = "Sample Code"
Run Code Online (Sandbox Code Playgroud)

app文件夹的build.gradle

apply plugin: 'kotlin-android-extensions'
Run Code Online (Sandbox Code Playgroud)

我的项目的build.gradle

 classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
Run Code Online (Sandbox Code Playgroud)

我的代码中有错误吗?请帮忙.我是Kotlin的新人.

android kotlin kotlin-extension kotlin-android-extensions

7
推荐指数
1
解决办法
623
查看次数

在Kotlin中具有对象的列表的深层副本

我是Kotlin的新手,正在尝试制作对象列表的副本。我遇到的问题是,当我更改新副本中的项目时,旧列表也会被更改。这是对象:

class ClassA(var title: String?, var list: ArrayList<ClassB>, var selected: Boolean)
class ClassB(val id: Int, val name: String) 
Run Code Online (Sandbox Code Playgroud)

我尝试这样做,但是不起作用:

val oldList:ArrayList<ClassA>


val newList :ArrayList<ClassA> = ArrayList()
newList.addAll(oldList)
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-extension kotlin-android-extensions

7
推荐指数
2
解决办法
5843
查看次数

Kotlin扩展功能-编译器无法推断nullable不为null

假设我有一个Foo带有可空值的简单类String?

data class Foo(
    val bar: String?
)
Run Code Online (Sandbox Code Playgroud)

我创建了一个简单的函数 capitalize

fun captitalize(foo: Foo) = when {
    foo.bar != null -> runCatching { foo.bar.capitalize() }
    else -> ""
}
Run Code Online (Sandbox Code Playgroud)

这很好用,因为尽管编译器推断foo.bar的类型可以为空,但它不能为null。但是后来我决定编写与扩展相同的函数Foo

fun Foo.captitalize2() = when {
    bar != null -> runCatching { bar.capitalize() }
    else -> ""
}
Run Code Online (Sandbox Code Playgroud)

突然编译器不再能够推断出bar不是null,而IntelliJ告诉我“在类型为null的接收者上仅允许安全(?。)或非null断言(!!。)调用。串?”

谁能解释为什么?

nullable kotlin kotlin-extension

7
推荐指数
1
解决办法
76
查看次数

Kotlin 获取没有实例的泛型类的类型

嘿,想要获取T 的类型,但我无法从实例中获取它,我必须从类参数中获取它,该怎么做?

abstract class ViewModelFragment<T : ViewModel>{
    protected lateinit var mViewModel: T

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
       mViewModel = ViewModelProviders
                    .of(scope)
                    .get(getGenericTClass())
    // .get(mViewModel.javaClass) // not working either

   }

   inline fun<reified R> getGenericTClass() = R::class.java

}
Run Code Online (Sandbox Code Playgroud)

现在编译器抱怨

不能使用“T”作为精炼的类类型。请改用 Class。

我尝试使用以下解决方案:https : //stackoverflow.com/a/34463352/2163045但对我不起作用

kotlin-extension

6
推荐指数
1
解决办法
1205
查看次数

在 Android 应用程序中声明 Kotlin 扩展函数的位置

假设我想将以下代码作为可重用的组件:

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
}
Run Code Online (Sandbox Code Playgroud)

我想在我的应用程序中的任何地方使用它,如下所示:

val l = mutableListOf(1, 2, 3)
l.swap(0, 2)
Run Code Online (Sandbox Code Playgroud)

如果我错了,请纠正我,但我相信函数扩展声明可以存在于类之外。那么在 Android 应用程序中,我应该把这个声明放在哪里?或者它甚至重要吗?compile 是否只编译代码,而不管扩展在哪里声明并使其可在全局范围内重用,还是必须使其成为类的一部分?

android kotlin kotlin-extension

6
推荐指数
1
解决办法
1612
查看次数

为什么扩展功能在另一个模块中不可见?

我的Android项目有两个模块:

app
common
Run Code Online (Sandbox Code Playgroud)

settings.gradle中:

rootProject.name='My project'
include ':app'
include ':common'
Run Code Online (Sandbox Code Playgroud)

在我的 build.gradle 中:

implementation project(':common')
Run Code Online (Sandbox Code Playgroud)

在公共包中,我有StringUtil.kt和下一个扩展函数:

fun String.isEmailValid(): Boolean {
    return !TextUtils.isEmpty(this) && android.util.Patterns.EMAIL_ADDRESS.matcher(this).matches()
}
Run Code Online (Sandbox Code Playgroud)

这个类中我可以使用这样的扩展函数:

val str = ""
str.isEmailValid()
Run Code Online (Sandbox Code Playgroud)

但在app模块中我有课

class RegistrationViewModel(application: Application) : AndroidViewModel(application) {

  fun doClickRegistration(email: String?, password: String?, retypePassword: String?) {
        val str = ""
        str.isEmailValid()
    }
}
Run Code Online (Sandbox Code Playgroud)

但现在我得到编译错误:

未解决的参考:isEmailValid

android kotlin kotlin-extension

6
推荐指数
1
解决办法
3527
查看次数