为什么创建片段时Android Studio使用let而不是运行

时间:2018-09-19 20:35:41

标签: android kotlin

当您使用File-> New-> Fragment

创建Fragment时,Android Studio会创建此代码。
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.let {
        param1 = it.getString(ARG_PARAM1)
        param2 = it.getString(ARG_PARAM2)
    }
}

run上使用arguments更好吗,因为您可以省略it?我知道您使用let来实现安全性,但是run也会给您Bundle,而不是Bundle?

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.run {
        param1 = getString(ARG_PARAM1)
        param2 = getString(ARG_PARAM2)
    }
}

使用let而不是run的原因是否特别?

2 个答案:

答案 0 :(得分:1)

FWIW,因为它们都返回一个值,所以它们都不是很有意义。

由于在这种情况下您不想返回值:

  • 如果要使用class MyWidget extends StatefulWidget { @override _MyWidgetState createState() => new _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { List<String> data = []; List<String> dataCopy = []; @override Widget build(BuildContext context) { data = dataCopy = getDataAsynchronously(); return Column( children: <Widget>[ TextField( onChanged: (text) { dataCopy.clear(); for (String s in data) if (s.toLowerCase().contains(text.toLowerCase())) dataCopy.add(s); setState(() {}); // can I avoid calling this ? }, ), Container( child: ListView.builder( itemCount: dataCopy.length, itemBuilder: (context, i) { return ListTile( title: Text( dataCopy.text, ), ); }, ), ) ], ); } } ,请使用also而不是it
  • 如果要使用接收器,请使用apply而不是let

而且...不,我不知道为什么Android Studio将使用run而不是let

答案 1 :(得分:0)

您看到那些“让它交配”的东西吗?这是两者唯一不同的地方。但是,因此,它们有不同的用途。首先,在运行时,调用“ this”将指向调用run的对象。因此,首先,将调用该对象具有的所有属性或方法。例如:

firebaseAuth!!.signInAnonymously()
        .addOnCompleteListener(this, OnCompleteListener<AuthResult> { task ->
            if (task.isSuccessful) {
                // Sign in success, update UI with the signed-in user's information
                Log.d(TAG, "signInAnonymously:success")
                Toast.makeText(this, "Authentication succeeded.",
                        Toast.LENGTH_SHORT).show()

                /* Assign 'user' */
                user = firebaseAuth!!.currentUser

                // Write a message to the database
                val database = FirebaseDatabase.getInstance()
                val uidPath: String? = user?.uid

                val uidRef = database.getReference("users")
                val nameRef = database.getReference("users/$uidPath/name")
                val emailRef = database.getReference("users/$uidPath/email")
                val authProviderRef = database.getReference("users/$uidPath/authProvider")

                uidRef.setValue("${user?.uid}")
                nameRef.setValue("${user?.displayName}")
                emailRef.setValue("${user?.email}")
                user?.providerData?.forEach {
                    authProviderRef.setValue(it.providerId)
                }
            } else {
                // If sign in fails, display a message to the user.
                Log.w(TAG, "signInAnonymously:failure", task.exception)
                Toast.makeText(this, "Authentication failed.",
                        Toast.LENGTH_SHORT).show()
            }
        })

这将调用对象的hello方法。但是,可以说是相同的情况,但是您要调用与对象的方法同名的函数。例如:

...
mObject?.run {
    hello();
}
...

这仍然可以工作,但是您仍然可以从对象运行问候。当使用let时,可以选择使用哪个对象的方法或函数。
P.S。 run可以单独运行,而let需要从变量等中访问。

奖金

此选项还有两个同时适用。现在,这两个与let and run有何不同? let and run可以返回自己或其他任何东西,或者完全不返回。在应用时,也将始终返回所使用的对象。而let的对应对象也是apply。

第二奖金

让我们说您要在使用对象之前检查其是否为空,然后设置其构造函数中未包含的属性。

...
fun hello() = print("not the hello from that object")
...
mObject?.run {
    hello();
}
...

但是,如果mObjectUndecided为null怎么办?

var mObject: MObject = mObjectUndecided?.also {
    // Do Something
}

但是,如果您需要调用与对象的mathod /属性相同的函数/变量,该怎么办?

val mObjectUndecided: MObject? = null
var mObject: MObject = mObjectUndecided?.apply{
    // Do Something
} ?: run {
    MObject().also {
        // Do Something
    }
}

但是,如果MObject是这样构造的:

val mObjectUndecided: MObject? = null
var mObject: MObject = mObjectUndecided?.let{
    // Do Something
    it // return it if its not null
} ?: run {
    MObject().also {
        // Do Something
    }
}

然后,您将必须嵌套它(也可以运行,运行,应用)。但是,您想在嵌套中的某个位置从更高的层次结构调用对象吗?

class MObject {
    var name: String? = null
    var mObjectNext: MObject? = null
}

P.P.S。还有一个叫做with的,对于这个上下文,我在这里谈论扩展功能并没有多大关系,但这值得一读。