当前位置: 首页 > 知识库问答 >
问题:

Kotlin在同伴对象中使用apply引发意外错误

督翰学
2023-03-14

然而,在同伴对象中使用apply时,我遇到了一个奇怪的意外错误。如果我在a的伙伴对象的函数中使用a().apply{},我会得到一个错误表达式无法从嵌套类'companion'访问,请使用'inner'关键字将类设为inner,这很奇怪,因为我直接对对象的实例调用apply,因此希望我始终能够访问它的公共属性。更不用说,似乎伴侣对象不能设置为inner,因此错误消息中的建议没有太大帮助。

下面是完整的示例代码:

fun main(args: Array<String>) {
    val b = B("Hello", "World")
    val a = A.fromB(b)

    print("$a.value1 $a.value2")
}


class A() {
    var value1: String? = null
    var value2: String? = null

    companion object {
        //This fails with "Expression is inaccessible from a nested class 'Companion', use 'inner' keyword to make the class inner"
        fun fromB(b: B): A {
            return A().apply {
                value1 = b.value3
                value2 = b.value4
            }
        }
    }
}

class B(val value3: String, val value4: String) {}

//This works
fun bToA(b: B): A {
    return A().apply {
                value1 = b.value3
                value2 = b.value4
            }
}

这是怎么回事?我做错了什么?

共有1个答案

慕容光启
2023-03-14

在我看来这是个虫子。可能与内联函数(例如apply)和伴随对象有关。我建议搜索JetBrains Bug&Issue Tracker,如果没有找到类似的内容,则创建一个新的问题。

与此同时,我看到了一些替代方案:

>

  • 使用(不理想):

    fun fromB(b: B): A {
        return A().apply {
            this.value1 = b.value3
            this.value2 = b.value4
        }
    }
    
    class A(var value1: String? = null, var value2: String? = null) {
        companion object {
            fun fromB(b: B): A {
                return A(
                        value1 = b.value3,
                        value2 = b.value4
                )
            }
        }
    }
    
    fun fromB(b: B) = with(b) {
        A(
                value1 = value3,
                value2 = value4
        )
    }
    

  •  类似资料:
    • 我想知道是否可以在同伴对象中使用类的属性。例如,以贝娄为例: 我不能通过c1或C2调用changeAge()函数。我可以使用changeAge的唯一地方是通过Person1.changeAge(),当Person1还没有用适当的构造函数实例化时。我想知道这些动作是不是有其他的选择,或者是没有,有同伴对象有什么意义呢

    • 可以省略陪伴对象的名称,在这种情况下,将使用名称: 但是,我看到的示例中没有使用同伴对象的名称。 因为每个类只能有一个同伴对象(否则会得到错误),所以这个名称对我来说就像是一些非常没用的语法糖。

    • 所以我有下面的代码,用Kotlin写的。 我在最后一条指令行()上得到一个编译错误,编译器说,但我不知道为什么。 我认为同伴对象应该对它们“陪伴”的类的属性具有某种可见性。 (免责声明:此代码正在从Java迁移到Kotlin。在Java版本上,以前是同一个类上的静态方法。) 多谢!

    • 我用Kotlin编写了这些方法并分析了字节码: null 上下文。我一直在Kotlin编码,我觉得它很神奇。但有时我需要做一个决定:例如,一个很重的不可变属性,在java中我会将其声明为static final,但在Kotlin中我发现很难“找到一个等价物”。

    • 带有同伴对象的简单示例类 值测试可以通过访问,但如何从MyClass的实例访问?如果我有,那么我如何从sample访问测试?不正确....有没有办法? Java,C++,python等都有很简单的解决方案...(我将为每个有帮助的is提供代码示例),我认为kotlin会有一个比使用Java更好的解决方案。 对于在没有对象实例(如工厂)的情况下访问类属性,kotlin companion objec

    • 在Kotlin的类中,一个对象和一个同伴对象有什么区别? 它的“静态”(我是java方面的)生命周期可能有区别吗?