溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android開發(fā)中dart是值傳遞還是引用傳遞

發(fā)布時間:2022-01-12 14:34:08 來源:億速云 閱讀:132 作者:iii 欄目:大數(shù)據(jù)

本文小編為大家詳細(xì)介紹“Android開發(fā)中dart是值傳遞還是引用傳遞”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Android開發(fā)中dart是值傳遞還是引用傳遞”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

一面問的 Java 和 Android 基礎(chǔ)

  1. Jvm 虛擬機(jī)
  2. messageQueue 會不會阻塞 ui 線程
  3. 對象鎖和類鎖
  4. 之字形打印樹

二面問的 Flutter 和 Dart

  1. dart 是值傳遞還是引用傳遞
  2. Widget 和 element 和 RenderObject 之間的關(guān)系
  3. widget 的 root 節(jié)點(diǎn)
  4. mixin extends implement 之間的關(guān)系(除了 extends 其他的沒怎么用過。。)
  5. jvm 內(nèi)存模型(感覺這個是面試官可憐我,看我什么都不會才問的=。=)
  6. Future 和 microtask 執(zhí)行順序
  7. dart 中..的用法(基本沒用過。。)
  8. await for(沒用過。。)

說實(shí)話,第一個、第三個、第六個我準(zhǔn)備的話應(yīng)該能答出來的,但是一個多月沒碰 Flutter 了,忘了都差不多。。。等下把二面的答案寫出來,希望能幫助后來人。此外 GitHub 和博客維護(hù)好很重要,像我這種 demo 隨手寫,隨手刪的人直接 GG。。

1. dart 是值傳遞還是引用傳遞

首先給個結(jié)論,dart 是引用傳遞。先來看段代碼

main(){
 Test a = new Test(5);
 print("a 的初始值為:${a.value}");
 setValue(a);
 print("修改后 a 的值為: ${a.value}");
}

class Test{
 int value = 1;
 Test(int newValue){
   this.value = newValue;
 }
}

setValue(Test s){
 print("修改 value 為 100");
 s.value = 100;
}
 

輸出結(jié)果為:

a 的初始值為:5
修改 value 為 100
修改后 a 的值為:100
 

從這里可以看出是引用傳遞,如果只是復(fù)制了一個對象的話,main 函數(shù)中的 a 值是不會發(fā)生變化的。

有些人可能會以以下代碼反駁我:

main(){
 int s = 6;
 setValue(s);
 print(s); //輸出 6,而不是 7
}

class Test{
 int value = 1;
 Test(int newValue){
   this.value = newValue;
 }
}

setValue(int s){
 s += 1;
}
 

你看,這輸出的不是 6 嗎,在 dart 中一切皆為對象,如果是引用傳遞,那為什么是 6 啊。

答案是這樣的,在 setValue() 方法中,參數(shù) s 實(shí)際上和我們初始化 int s = 6 的 s 不是一個對象,只是他們現(xiàn)在指的是同一塊內(nèi)存區(qū)域,然后在 setValue() 中調(diào)用 s += 1 的時候,這塊內(nèi)存區(qū)域的對象執(zhí)行+1 操作,然后在堆 (類比 java) 中產(chǎn)生了一個新的對象,s 再指向這個對象。所以 s 參數(shù)只是把 main 函數(shù)中的 s 的內(nèi)存地址復(fù)制過去了,就比如 java 中的:

public class Test {
   public static void main(String[] args) {
       Test a = new Test();
       Test b = a;
       b = new Test();
   }
}
 

我們只要記住一點(diǎn),參數(shù)是把內(nèi)存地址傳過去了,如果對這個內(nèi)存地址上的對象修改,那么其他位置的引用該內(nèi)存地址的變量值也會修改。千萬要記住 dart 中一切都是對象。

偷偷說一句,我覺得面試官這個地方面試的不好,這種細(xì)節(jié)問題,如果不是遇到什么 bug,業(yè)務(wù)忙的時候是沒時間注意這個的,面試官可以把這兩種情況展示下,然后問面試者原因是什么。。然后我就能回答出來了。??捱筮蟆?。

2. Widget 和 element 和 RenderObject 之間的關(guān)系

首先我詳細(xì)說下當(dāng)時的情景,面試官問我 Widget 和 Element 之間是不是一對多的關(guān)系,如果是增加一個 Widget 之后,這個關(guān)系又是什么。

這部分還是沒有很好地答案,現(xiàn)在只是一個猜想,如果添加了一個 widget,Element 樹遍歷后面所有的 Element 看類型是否發(fā)生改變,有的話再重建 RenderObject。

Element 和 Widget 之間應(yīng)該還是一對一的關(guān)系,因?yàn)槊總€ Widget 的 context 都是獨(dú)一無二的。等想好了再寫上去吧。

3. widget 樹的 root 節(jié)點(diǎn)

還是沒能理解面試官的意思。。有能夠理解的同學(xué)請?jiān)u論告知我一下?,F(xiàn)在理解了,面試官的意思應(yīng)該指是 runApp() 方法中的那個的 Widget。我當(dāng)時也想說的不過忘記這個方法名是啥了。。。

4. mixin extends implement 之間的關(guān)系

這部分可以參考掘金的小德大佬的文章,高產(chǎn)似那啥。。Flutter Dart mixins 探究 Flutter Dart 語法 (1):extends 、 implements 、 with 的用法與區(qū)別

6. Future 和 microtask 執(zhí)行順序同樣參考小德的文章深入了解 Flutter 的 isolate(1) ---- 事件循環(huán) (event loop) 及代碼運(yùn)行順序深入了解 Flutter 的 isolate(2) --- 創(chuàng)建自己的 isolate 深入了解 Flutter 的 isolate(3) --- Flutter 的 thread model(線程模型)深入了解 Flutter 的 isolate(4) --- 使用 Compute 寫 isolates

7. dart 中..是什么級聯(lián)符號 .. 可以讓你連續(xù)操作相同的對象,不單可以連續(xù)地調(diào)用函數(shù),還可以連續(xù)地訪問方法,這樣做可以避免創(chuàng)建臨時變量,從而寫出更流暢的代碼,流式編程更符合現(xiàn)代編程習(xí)慣和編程風(fēng)格:

main(){
 Tree tree = new Tree(1);
 tree..test1 = 1..test2 =5;
 print(tree.test1);
 print(tree.test2);
}

class Tree{
 int value;
 int test1 = 2;
 int test2 = 3;
 Tree(int a){
   this.value = a;
 }
}
 

8. await for 使用先來一段官方文檔

await-forAs every Dart programmer knows, the for-in loop plays well with iterables. Similarly, the await-for loop is designed to play well with streams.Given a stream, one can loop over its values:Every time an element is added to the stream, the loop body is run. After each iteration, the function enclosing the loop suspends until the next element is available or the stream is done. Just like await expressions, await-for loops can only appear inside asynchronous functions.

大概意思就是 await for 是不斷獲取 stream 流中的數(shù)據(jù),然后執(zhí)行循環(huán)體中的操作。

Stream<String> stream = new Stream<String>.fromIterable([' 不開心 ', ' 面試 ', ' 沒 ', ' 過 ']);
main() async{
 print(' 上午被開水燙了腳 ');
 await for(String s in stream){
   print(s);
 }
 print(' 晚上還沒吃飯 ');
}
 

輸出為

上午被開水燙了腳
不開心
面試


晚上還沒吃飯
 

await for 和 listen 的作用很相似,都是獲取流中數(shù)據(jù)然后輸出,但是正如 await for 中的 await 所示,如果 stream 沒有傳遞完成,就會一直阻塞在這個位置,上面沒吃飯是最后輸出的,下面給個 listen 的實(shí)例,一看就懂。

Stream<String> stream = new Stream<String>.fromIterable([' 不開心 ', ' 面試 ', ' 沒 ', ' 過 ']);
main(){
 print(' 上午被開水燙了腳 ');
 stream.listen((s) { print(s); });
 print(' 晚上還沒吃飯 ');
}
 

輸出為

上午被開水燙了腳
晚上還沒吃飯
不開心
面試

所以 await for 一般用在直到 stream 什么時候完成,并且必須等待傳遞完成之后才能使用,不然就會一直阻塞,造成類似于 Android ANR 的問題。

讀到這里,這篇“Android開發(fā)中dart是值傳遞還是引用傳遞”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI