标签: kotlin-extension

在kotlin中,如何返回泛型类参数定义的实例

我正在尝试为kotlin 1.0.3的Web框架编写一个很好的Kotlin包装器.在那里我试图将一个函数混合到请求中,让它通过使用jackson的JSON转换返回一个bean.

所以在我的图书馆里,我有以下内容

private val mapper: ObjectMapper = ObjectMapper().registerModule(KotlinModule())
fun <T : Any> Request.asDataBean(type: KClass<T>): T = mapper.readValue(this.body(), type.java)
Run Code Online (Sandbox Code Playgroud)

但是当我转到使用代码时

post("/hello", { req, res ->
    val bean = req.asDataBean(TestBean::class)
})
Run Code Online (Sandbox Code Playgroud)

它错误地说bean的期望值是Any.我想要的是我的API如上所述工作,其中传递给asDataBean方法的通用"类"定义是返回的值的类型.

我也试过了

fun <T> Request.asDataBean(type: KClass<*>): T = mapper.readValue(this.body(), type.java) as T
Run Code Online (Sandbox Code Playgroud)

以及将使用代码更改为

val bean: TestBean = req.asDataBean(TestBean::class)
Run Code Online (Sandbox Code Playgroud)

希望使它工作,但他们在使用代码时也会给出完全相同的错误.

我如何使用传入的类类型定义的泛型作为参数(非常类似于所有spring api在java中的工作方式)?

generics kotlin kotlin-extension

5
推荐指数
2
解决办法
2707
查看次数

Android Kotlin Extension超级调用

我是Java Android开发人员,我正在接近Kotlin

我已经定义了以下类:

open class Player : RealmObject() {
    ...
}
Run Code Online (Sandbox Code Playgroud)

我定义了以下两个扩展,一个用于通用的RealmObject类,另一个用于特定的Player类:

fun RealmObject.store() {
    Realm.getDefaultInstance().use { realm ->
        realm.beginTransaction()
        realm.copyToRealmOrUpdate(this)
        realm.commitTransaction()
    }
}

fun Player.store(){
    this.loggedAt = Date()
    (this as RealmObject).store()
}
Run Code Online (Sandbox Code Playgroud)

我想要的是如果我调用.store()任何RealmObject对象,RelamObject.store()扩展名将被调用但是如果我.store()在一个Player实例上调用将被调用的扩展名Player.store().(现在没问题)我不想复制粘贴相同的代码,我喜欢写更少的重用更多.所以我需要在内部Player.store()调用泛型RealmObject.store()

我知道了.我在那里写的代码实际上按预期工作:D

我要问的是(仅仅因为我是通过个人直觉写的):

这是好方法吗?!还是有更好的方法?

谢谢

super kotlin kotlin-extension kotlin-android-extensions

5
推荐指数
1
解决办法
333
查看次数

布尔扩展函数

当我尝试创建扩展函数以设置布尔值true或false时,如下所示.

Boolean.setTrue(){
 this = true
}

Boolean.setFalse(){
 this = false
}
Run Code Online (Sandbox Code Playgroud)

它表示预期变量.如何实现这一目标.

boolean kotlin kotlin-extension

5
推荐指数
1
解决办法
906
查看次数

Kotlin 成员和扩展同时使用

为了更多地了解 Kotlin 并尝试使用它,我正在开发一个示例 Android 应用程序,我可以在其中尝试不同的东西。

但是,即使在该主题上搜索了一段时间后,我也无法为以下问题找到正确的答案:

让我们在 View 类上声明一个(虚拟)扩展函数:

fun View.isViewVisibility(v: Int): Boolean = visibility == v
Run Code Online (Sandbox Code Playgroud)

现在我怎样才能从其他地方引用这个函数以便以后调用 invoke() 呢?

val f: (Int) -> Boolean = View::isViewVisibility
Run Code Online (Sandbox Code Playgroud)

目前给我:

错误:(57, 35) 类型不匹配:推断类型为 KFunction2 但 (Int) -> Boolean was expectedError:(57, 41) 'isViewVisibility' 同时是成员和扩展。不允许引用此类元素

有什么解决方法吗?谢谢 !

kotlin kotlin-extension

5
推荐指数
2
解决办法
1833
查看次数

Kotlin扩展方法作为长方法名的别名?

我在Kotlin工作,使用包含方法的Kotlin本地库对象.nameIsMuchTooLongAndIsStillNotClear.以类似的方式typealias,我想为方法创建一个别名,所以我可以将它称为某种东西.shortAndClear.稍微复杂一点,这些函数有几个参数,其中许多都有默认值,我不想在包装器中预处理.经过进一步的研究,它似乎仍然是一种扩展功能.

要使用示例函数,很容易测试,让我们说我要为创建别名类型的扩展String.startsWith被称为String.beg.我可以很容易地得到以下解决方案:

inline fun String.beg(prefix: CharSequence, ignoreCase: Boolean = false) = startsWith(prefix, ignoreCase)   // works ok
Run Code Online (Sandbox Code Playgroud)

但是,这似乎要求我列出所有参数及其默认值,并为每次重载执行此操作.(真正的方法签名相当长,有更多的默认值.)本着"不要重复自己"的精神,有没有办法可以使用函数引用,String::startsWith这样我就不必枚举所有参数?我尝试了几种形式,但它们都不起作用:

// none of these work:
fun String.beg = String::startsWith
fun String.beg = this::startsWith
val String.beg: (CharSequence, Boolean) -> Boolean = String::startsWith
Run Code Online (Sandbox Code Playgroud)

extension-methods kotlin kotlin-extension

5
推荐指数
2
解决办法
1390
查看次数

无法使用Kotlin访问EditText或其他UI组件

我正在使用Android Studio 3.0 RC2和Kotlin.

当我尝试访问UI组件时,应用程序崩溃,除非我首先编写findViewById.我以为Kotlin应该摆脱不得不写findViewById线?UI是一个fragment,我试图从相同的fragment代码访问.有没有办法不用写findViewById?

这些行有效:

var userNameField = view?.findViewById<EditText>(R.id.userNameTextField) as EditText
userNameField.setText("hello world")
Run Code Online (Sandbox Code Playgroud)

没有findViewById行,此行不起作用

userNameTextField.setText("hello world")
Run Code Online (Sandbox Code Playgroud)

我甚至有

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

onCreateView()代码:

 override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    var view = inflater!!.inflate(R.layout.fragment_sign_in, container, false)

    var userNameField = view?.findViewById<EditText>(R.id.userNameTextField) as EditText
    userNameField.setText("hello world")

    return view
}
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-extension android-studio-3.0

5
推荐指数
1
解决办法
625
查看次数

在 Android Java 应用程序中使用 Kotlin AAR 时出现 java.lang.NoClassDefFoundError

我必须在 Kotlin 中制作一个库(aar),并且必须在使用 Java 制作的 Android 应用程序中使用它。Kotlin 库有一个带有配套函数的类,可以在 Java 应用程序中静态使用。当我在 Java 的 Android 应用程序中使用该静态方法时,我确实收到了“ClassNotFoundException”。任何人都可以帮助我如何在 Android Java 应用程序的 aar 中使用配套方法。请找到我的代码片段和运行我的应用程序时遇到的异常。并且只有在 Android Java 项目中使用 Kotlin AAR 而不是在 Android Kotlin 项目中使用时,我才会收到此错误。Kotlin 库或 Android Java 项目中是否缺少某些东西。Kotlin 库片段:

class LogUtil {
    companion object {
        private const val LOG_TAG = "KOTLIN_LIBRARY"
        @JvmStatic
        fun log(message: String) {
            Log.i(LOG_TAG, message)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Android 活动片段:

public class MainActivity extends AppCompatActivity {

    private HaloSDK haloSDK;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        testKotlinSDK();
    }


    private void testKotlinSDK() { …
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-extension kotlin-android-extensions

5
推荐指数
1
解决办法
3693
查看次数

Kotlin中是否可以将内联函数和when表达式与扩展函数结合在一起?

我想减小if-elseif-else梯形图的大小,但不能仅仅when因为智能广播无法捕获我正在处理的情况而使用。我想知道是否可以将诸如a let或an also和a之类的内容组合when到单个内联函数中以解决此问题。

我已经尝试过将智能投射与一起使用,is但这是有问题的,因为我必须when在外部when进行a 运算才能真正获得想要的结果。我最终做了与这篇文章中的一个响应类似的事情:Kotlin和惯用的方式,基于可变的值,通过使一个let块作用于非null变量,然后执行,来编写“如果不为null,否则...”when内部的块let

案例我目前正在处理:

variable?.let { safeVariable ->
    when {
        case1 -> doSomething(safeVariable)
        case2 -> doSomethingElse(safeVariable)
         ...
        else -> catchAll(safeVariable)
    }
    return@let
}
Log.e(TAG, "variable was null")
Run Code Online (Sandbox Code Playgroud)

我考虑过的案例:

when(variable) {
    is Type -> when {
                   case1 -> doSomething(variable)
                   case2 -> doSomethingElse(variable)
                   ...
                   else -> catchAll(variable)
               }
   else -> Log.e(TAG, "variable was null")
}
Run Code Online (Sandbox Code Playgroud)
if (variable is …
Run Code Online (Sandbox Code Playgroud)

generics kotlin kotlin-extension kotlin-android-extensions

5
推荐指数
1
解决办法
72
查看次数

具有依赖于接收器类型参数的泛型类型的 Kotlin 扩展函数(未明确指定)

有时我想在泛型类型上有一个扩展函数,其参数或返回值是给定类型参数的子类型,但不必指定实际类型参数。(也许,如果不清楚,代码会更好地阐明它?)

使用此答案的签名:

inline fun <reified U : T, T> Iterable<T>.partitionByType(): Pair<List<U>, List<T>>
Run Code Online (Sandbox Code Playgroud)

它迫使我按如下方式使用它:

val list : List<SomeType>
list.partitionByType<InterestedType, SomeType>()
Run Code Online (Sandbox Code Playgroud)

但是,我更想写的是以下内容:

list.partitionByType<InterestedType>()
Run Code Online (Sandbox Code Playgroud)

其中InterestedType是列表的类型参数的子类型,即SomeType. 上面的两个解决方案都应该给我Pair<List<InterestedType>, List<SomeType>>作为返回值。

然而,这实际上是不可能的。我想到的最好的是类似于以下的签名:

 inline fun <reified U : Any> Iterable<Any>.partitionByType(): Pair<List<U>, List<Any>>
Run Code Online (Sandbox Code Playgroud)

但是随后我们丢失了其他已知的实际类型T/ SomeType。调用方仍然可以进行未经检查的强制转换,但这不是我所追求的。

所以我的问题是:这有可能吗?有类似的东西U : T,没有指定T?或者在这方面有什么计划(KEEP 或 Kotlin 问题可用)?

对我来说,这听起来像是一个合理的功能,至少只要它仅应用于扩展功能。如果不是,那么我目前可能只是忽略/忽略的问题是什么?我并不是真正要寻找的是一种解决方法(例如具有中间类型),但将其作为答案也可能是值得的。

我想得越多。如果泛型类型的扩展函数声明如下,不是更正确吗?

fun SomeType<T>.extended()
Run Code Online (Sandbox Code Playgroud)

代替

fun <T> SomeType<T>.extended()
Run Code Online (Sandbox Code Playgroud)

因为:如果我在控制之下SomeType<T>并将在那里添加该函数,我将不需要任何泛型类型信息来声明它,例如以下内容就足够了:

fun extended()
Run Code Online (Sandbox Code Playgroud)

具有自己的泛型类型的函数也是如此,例如:

fun <U : T> extended2()
Run Code Online (Sandbox Code Playgroud)

现在将其添加为扩展函数会强制添加该T-generic 类型,尽管我们希望应用它的类型显然是 …

generics kotlin kotlin-extension

5
推荐指数
1
解决办法
869
查看次数

如何在okhttp 4中使用新的扩展功能

从okHttp版本3升级到版本4时,您遇到了此编译错误:

val JSON = MediaType.parse("application/json; charset=utf-8")
//Compile Error: Kotlin: Using 'parse(String): MediaType?' is an error. moved to extension function
Run Code Online (Sandbox Code Playgroud)

我更改了将扩展方法作为错误点的调用,但该方法未被识别为String扩展。

这是我的更改方式:

val JSON = "application/json; charset=utf-8".toMediaType()
Run Code Online (Sandbox Code Playgroud)

教程中所述,为Companion对象添加导入也无法解决该问题:

import okhttp3.CipherSuite.Companion.forJavaName
Run Code Online (Sandbox Code Playgroud)

我在这里想念什么?

kotlin okhttp kotlin-extension okhttp3

5
推荐指数
1
解决办法
934
查看次数