在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) 经过几个小时的搜索,我决定问这个问题.为什么这个正则表达式:^(dog).+?(cat)?不起作用,因为我认为它应该工作(捕获第一只狗和猫,如果有的话)?我在这里错过了什么?
dog, cat
dog, dog, cat
dog, dog, dog
Run Code Online (Sandbox Code Playgroud) 从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如何消除函数调用,构造函数,伴随对象和调用重载的歧义?在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) 我需要在shell环境中运行Gradle任务,该环境必须在启动任务之前创建.使用commandLine或executable不合适,因为我需要在与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或轻松解析.
官方的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中?
您可以将房产委托给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 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 中,有一种有限形式的具体化泛型。有没有什么方法可以使用具体化来过滤通用类型,而不使用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) 通常,我有以下模式:
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?
在将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尝试在同一时间内使用所有变体进行单一构建或什么?)
我真的很喜欢在 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)
有什么技巧可以让这个更简洁吗?