小编bre*_*dan的帖子

擦除如何在Kotlin工作?

在Kotlin中,以下代码编译:

class Foo {
    fun bar(foo: List<String>): String {
        return ""
    }

    fun bar(foo: List<Int>): Int {
        return 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,此代码不会:

class Foo {
    fun bar(foo: List<String>): String {
        return ""
    }

    fun bar(foo: List<Int>): String {
        return "2";
    }
}
Run Code Online (Sandbox Code Playgroud)

编译它会导致以下错误:

Error:(8, 5) Kotlin: Platform declaration clash: The following declarations have the same JVM signature (foo(Ljava/util/List;)Ljava/lang/String;):
    fun foo(layout: List<Int>): String
    fun foo(layout: List<String>): String
Run Code Online (Sandbox Code Playgroud)

在Java中,两个示例都不会编译:

class Foo {
    String bar(List<Integer> foo) {
        return "";
    }

    Integer bar(List<String> foo) …
Run Code Online (Sandbox Code Playgroud)

kotlin

21
推荐指数
2
解决办法
2338
查看次数

正则表达式可选捕获组?

经过几个小时的搜索,我决定问这个问题.为什么这个正则表达式:^(dog).+?(cat)?不起作用,因为我认为它应该工作(捕获第一只狗和猫,如果有的话)?我在这里错过了什么?

dog, cat
dog, dog, cat
dog, dog, dog
Run Code Online (Sandbox Code Playgroud)

regex optional capturing-group

20
推荐指数
3
解决办法
4万
查看次数

为什么属性初始值设定项不会调用自定义setter?

Kotlin文档中,允许使用自定义setter:

class Test {
  var stringRepresentation: String
    get() = field
    set(value) {
      setDataFromString(value) 
    }

  init {
    stringRepresentation = "test"
  }

  private fun setDataFromString(value: String) { }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果没有自定义getter(并从init块中初始化),则无法拥有自定义setter :

class Test {
  // Compilation error: "Property must be initialized"
  var stringRepresentation: String
    set(value) {
      setDataFromString(value)
    }

  init {
    stringRepresentation = "test"
  }

  private fun setDataFromString(value: String) { }
}
Run Code Online (Sandbox Code Playgroud)

虽然你可以有一个没有自定义setter的自定义getter,但这里没问题:

class Test {
  var stringRepresentation: String
    get() = field 

  init {
    stringRepresentation = "test"
  }

  private …
Run Code Online (Sandbox Code Playgroud)

kotlin

15
推荐指数
1
解决办法
1449
查看次数

Kotlin如何调度invoke运算符?

Kotlin如何消除函数调用,构造函数,伴随对象和调用重载的歧义?在Kotlin 1.3.11,我可以在同一范围内声明两个同名成员:

fun main(args: Array<String>) {
    val test = object {
        operator fun invoke() = println("test invocation")
    }

    test() // Prints: "test invocation"

    // I think this should fail to compile, but it works
    fun test() = println("test function")

    test() // Prints: "test function"
}
Run Code Online (Sandbox Code Playgroud)

您可能认为它使用了最新的声明,但并非如此!

fun main(args: Array<String>) {
    fun test() = println("test function")

    val test = object {
        operator fun invoke() = println("test invocation")
    }

    test() // Prints: "test function"
}
Run Code Online (Sandbox Code Playgroud)

但是范围也有一些奇怪的互动.如果我在外面移动函数声明:

fun test() = println("test function") …
Run Code Online (Sandbox Code Playgroud)

kotlin

10
推荐指数
1
解决办法
514
查看次数

使Gradle任务可以访问环境变量

我需要在shell环境中运行Gradle任务,该环境必须在启动任务之前创建.使用commandLineexecutable不合适,因为我需要在与shell脚本相同的进程中运行任务.最初,我直接在里面调用了脚本gradlew,但后来我决定从中获取源代码build.gradle.kts并通过gradlew以下方式调用后续任务:

val setupRosEnv by tasks.creating(Exec::class) {
    executable = "bash"

    args("-c", "source $rosPath/setup.sh && source gradlew myTask")
}
Run Code Online (Sandbox Code Playgroud)

我可以通过./gradlew setupRosEnvCLI 运行来构建所有内容.除了运行脚本然后运行gradlew,有没有办法使用Gradle API实现这一点?当前的解决方案看起来有点笨拙,而且依赖于其他任务很笨拙setupRosEnv,因为这将导致无限循环或必须明确处理以防止任务多次运行.

由于shell脚本本身是由ROS生成的,因此无法将其转换为Gradle或轻松解析.

bash gradle kotlin ros gradle-kotlin-dsl

9
推荐指数
1
解决办法
987
查看次数

nvidia-docker是否可以在没有GPU的情况下运行?

官方的PyTorch Docker映像基于nvidia/cuda,可以在Docker CE上运行,而无需任何GPU。它也可以在nvidia-docker上运行,我假设已启用CUDA支持。是否可以在没有任何GPU的x86 CPU上运行nvidia-docker本身?有没有一种构建单个Docker映像的方法,该映像在可用时(例如,在内部运行时nvidia-docker)利用CUDA支持,否则使用CPU?torch.cuda在Docker CE内部使用时会发生什么?Docker CE之间到底有什么区别,为什么不能nvidia-docker合并到Docker CE中?

cuda docker pytorch nvidia-docker

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

将财产委托给另一个财产

您可以将房产委托给Kotlin的另一处房产吗?我有以下代码:

class SettingsPage {
  lateinit var tagCharacters: JTextField
  lateinit var tagForegroundColorChooser: ColorPanel
  lateinit var tagBackgroundColorChooser: ColorPanel

  var allowedChars: String
    get() = tagCharacters.text
    set(value) = tagCharacters.setText(value)

  var tagForegroundColor by tagForegroundColorChooser
  var tagBackgroundColor by tagBackgroundColorChooser
}
Run Code Online (Sandbox Code Playgroud)

为了获得属性委托,我声明了以下两个扩展函数:

  operator fun ColorPanel.getValue(a: SettingsPage, p: KProperty<*>) = selectedColor
  operator fun ColorPanel.setValue(a: SettingsPage, p: KProperty<*>, c: Color?) { selectedColor = c }
Run Code Online (Sandbox Code Playgroud)

但是,我想写的内容如下:

class SettingsPage {
  lateinit var tagCharacters: JTextField
  lateinit var tagForegroundColorChooser: ColorPanel
  lateinit var tagBackgroundColorChooser: ColorPanel

  var allowedChars: String by Alias(tagCharacters.text)
  var tagForegroundColor by …
Run Code Online (Sandbox Code Playgroud)

kotlin

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

具有通用返回类型的高阶函数的类型推断

以下示例在Kotlin 1.3.21中是完全合法的:

fun <T> foo(bar: T): T = bar

val t: Int = foo(1) // No need to declare foo<Int>(1) explicitly
Run Code Online (Sandbox Code Playgroud)

但是为什么类型推断不能用于高阶函数呢?

fun <T> foo() = fun(bar: T): T = bar

val t: Int = foo()(1) // Compile error: Type inference failed...
Run Code Online (Sandbox Code Playgroud)

使用高阶函数时,Kotlin会强制呼叫站点为:

val t = foo<Int>()(1)
Run Code Online (Sandbox Code Playgroud)

即使foo明确指定了返回类型,类型推断仍然会失败:

fun <T> foo(): (T) -> T = fun(bar: T): T = bar

val t: Int = foo()(1) // Compile error: Type inference failed...
Run Code Online (Sandbox Code Playgroud)

但是,当泛型类型参数与外部函数共享时,它将起作用!

fun <T> foo(baz: T) = fun …
Run Code Online (Sandbox Code Playgroud)

kotlin

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

过滤通用类型,无需反射或转换

在 Kotlin 中,有一种有限形式的具体化泛型。有没有什么方法可以使用具体化来过滤通用类型,而不使用getClass()as或任何类型的奇怪注释,即。只需使用is关键字?例如,我有以下结构:

import java.util.*

internal class Layout<out T : LayoutProtocol>(val t: T) {
    fun getName(): String {
        return t.getName()
    }
}

interface LayoutProtocol {
    fun getName(): String
}

internal class Vertical : LayoutProtocol {
    override fun getName(): String {
        return "Vertical"
    }
}

internal class Horizontal : LayoutProtocol {
    override fun getName(): String {
        return "Horizontal"
    }
}

fun main(args: Array<String>) {
    val layouts = LinkedList<Layout<*>>()
    layouts.add(Layout<Horizontal>(Horizontal()))
    layouts.add(Layout<Vertical>(Vertical()))
    println("Horizontal layouts:")
    layouts.filterIsInstance<Layout<Horizontal>>().forEach …
Run Code Online (Sandbox Code Playgroud)

generics reification kotlin

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

在多个接收器上调用常用方法

通常,我有以下模式:

a.x()
a.y()
a.z()
Run Code Online (Sandbox Code Playgroud)

Kotlin提供了一个方便的替代方案:

a.run { x(); y(); z() }
Run Code Online (Sandbox Code Playgroud)

有时我有这样的模式:

a.x()
b.x()
c.x()
Run Code Online (Sandbox Code Playgroud)

我想写这样的东西:

applyTo(a, b, c) { it.x() }
Run Code Online (Sandbox Code Playgroud)

所以我可能会实现以下内容:

fun <P> applyTo(vararg ps: P, fx: (P) -> Unit) = ps.forEach { fx(it) }
Run Code Online (Sandbox Code Playgroud)

或者,或者像这样:

::x.eachOf(a, b, c)
Run Code Online (Sandbox Code Playgroud)

所以我可以实现这个功能:

fun <P, R> ((P) -> R).eachOf(vararg p: P) = p.forEach { this(it) }
Run Code Online (Sandbox Code Playgroud)

有没有办法使用标准库在多个接收器上调用共享方法,或者更好地缩短模式#2?

kotlin

3
推荐指数
1
解决办法
189
查看次数

Gadle 3.0 Flavor错误重复类

在将Android Studio和Gradle更新到3.0版后,我无法使用3种风格(dbg,production和nostore production)构建我的应用程序
在每个风味源集的java/src文件夹中(排除main)我有一些Flavors.class类和一些为此源集指定的方法.
但是当我尝试运行或构建应用程序时,我有错误: Error:(9, 8) error: duplicate class: my.app.namespace.Flavors.
此外,我添加gradle变量维度flavorDimensions "dbg", "prod","nostore"dimension为每个风味部分添加值.
这是它的外观:

android{
   compileSdkVersion 24
   buildToolsVersion '26.0.2'
   ...
   flavorDimensions "dbg", "prod","nostore"
   productFlavors {

    dbg{
        ndk {
            abiFilters "armeabi", "x86"
        }
        dimension "dbg"
    }

    production{
        ndk {
            abiFilters "armeabi", "x86"
        }
        dimension "prod"
    }

    nostoreprod {
        ndk {
            abiFilters "armeabi", "x86"
        }
        dimension "nostore"
    }
  }     
}
Run Code Online (Sandbox Code Playgroud)

我不明白什么是错的,这段代码看起来像https://developer.android.com/studio/build/build-variants.html上的示例.
有一点,在Build Varians面板上,我现在只有2个varians:dbgProductionNostoreprodDebug和dbgProductionNostoreprodRelease但是在之前的AS和Gradle版本中,我对这个面板上的每种风格都有不同的变体.(看起来像AStudio尝试在同一时间内使用所有变体进行单一构建或什么?)

android gradle android-studio android-studio-3.0

2
推荐指数
1
解决办法
633
查看次数

Kotlin 接口可以缓存值吗?

我真的很喜欢在 Kotlin 中使用接口的默认实现,尤其是像 Observable 这样的常见模式。这是我的界面,

interface Observable<T>{

    // How do I cache this?
    val observers: MutableList<Observer<T>>
        get() = LinkedList<>()

    fun addObserver(o:Observer<T>){
        observers.add(o)
    }

    fun removeObserver(o:Observer<T>){
        observers.remove(o)
    }

    fun notifyObservers(u:T){
        for (o in observers){
            o.update(u)
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

该接口引用了 的列表observers,但调用每次get()都会返回一个新的。LinkedList()如何缓存 的值observers以便仅创建一次?我尝试过使用kotlin-lazy,但要么无法获得正确的语法,要么它不适用于接口。我的 IDE 抱怨“接口中不允许使用委托属性。”

更新

根据 Yoav 的回答,我已将界面更改为

interface Observable<T>{
    val observers: MutableList<Observer<T>>
}
Run Code Online (Sandbox Code Playgroud)

然后在实现类中,

class MyObservable : Observable<String>

   private val _observers = LinkedList<Observer<String>>()

   override val observers: MutableList<Observer<String>>
       get() = _observers
Run Code Online (Sandbox Code Playgroud)

有什么技巧可以让这个更简洁吗?

java observable kotlin

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