我正在尝试为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中的工作方式)?
我是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
我要问的是(仅仅因为我是通过个人直觉写的):
这是好方法吗?!还是有更好的方法?
谢谢
当我尝试创建扩展函数以设置布尔值true或false时,如下所示.
Boolean.setTrue(){
this = true
}
Boolean.setFalse(){
this = false
}
Run Code Online (Sandbox Code Playgroud)
它表示预期变量.如何实现这一目标.
为了更多地了解 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本地库对象.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) 我正在使用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) 我必须在 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) 我想减小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) 有时我想在泛型类型上有一个扩展函数,其参数或返回值是给定类型参数的子类型,但不必指定实际类型参数。(也许,如果不清楚,代码会更好地阐明它?)
使用此答案的签名:
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 类型,尽管我们希望应用它的类型显然是 …
从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)
我在这里想念什么?