【问题标题】:Android kotlin - secondary constructorAndroid kotlin - 辅助构造函数
【发布时间】:2018-09-01 13:37:57
【问题描述】:

我想实现一个有两个构造函数的类。空的构造函数和另一个带有参数user:FirebaseUser

但我收到消息错误:

“委托变更存在循环”

class UserModel(user: FirebaseUser) {

    var uid: String?
    val email: String?
    val phoneNumber: String?
    val photoUrl: String
    val displayName: String?

    //error message: There is a cycle in the delegation change
    constructor():this() {}


    init {
        this.displayName = user.displayName
        this.email = user.email
        this.phoneNumber = user.phoneNumber
        this.photoUrl = user.photoUrl!!.toString()
        this.uid = user.uid
    }



    companion object {

        @Exclude
        val CURRENT_LOCATION = "location"
    }

}

我尝试了几种方法都没有成功。有什么帮助吗?

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    所有辅助构造函数都必须直接或间接调用主构造函数。这意味着:

    class X(var x: Int){
        constructor() : this(0.0);
        constructor(x: Double) : this(x.toInt());
    }
    

    但是,你不能这样做:

    class X(var x: Int){
        constructor() : this();
        constructor(x: Double) : this();
    }
    

    因为它会导致堆栈溢出异常。

    上面的例子是可怕的代码,但它只是一个演示。

    所以用这一行:

    constructor():this() {}
    

    您使辅助构造函数自己调用。

    改为调用主构造函数。这意味着您需要传递 FirebaseUser 作为参数。我不熟悉 Firebase,所以我将把它留给你。

    但作为一个例子,你基本上需要这样做:

    constructor() : this(FirebaseUser());
    

    要么直接初始化,要么从方法中获取。如果你不能得到一个,你当然可以让它为空。

    但是,如果您正在处理可空值,假设您的大部分代码都在 Kotlin 中,您可以使用默认值将其设为可空值并移除辅助构造函数:

    class UserModel(user: FirebaseUser? = null){
        init{
            // Now that `user` is nullable, you need to change the assignments to include null-safe or non-null assertion (?. or !!. respectively)
        }
    }
    

    【讨论】:

      【解决方案2】:

      您必须从您拥有的每个辅助构造函数中调用主构造函数,因为它的参数可能用于属性初始化程序和初始化程序块,就像您在代码中的 init 块中使用了 user 一样。

      使用此代码,辅助构造函数只是递归调用自身:

      constructor() : this() {}
      

      您应该做的是调用主构造函数,以便可以初始化类的属性:

      constructor() : this(FirebaseUser()) {} // get FirebaseUser from somewhere
      

      或者,如果您的意思是在调用辅助无参数构造函数时保留所有 null,您可以选择这样的方式:

      class UserModel(user: FirebaseUser?) {
      
          var uid: String? = user?.uid
          val email: String? = user?.email
          val phoneNumber: String? = user?.phoneNumber
          val photoUrl: String? = user?.photoUrl?.toString()
          val displayName: String? = user?.displayName
      
          constructor() : this(null)
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-10
        • 1970-01-01
        • 1970-01-01
        • 2017-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多