

<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kotlin &#8211; Max的程式語言筆記</title>
	<atom:link href="https://stackoverflow.max-everyday.com/tag/kotlin/feed/" rel="self" type="application/rss+xml" />
	<link>https://stackoverflow.max-everyday.com</link>
	<description>我要當一個豬頭，快樂過每一天</description>
	<lastBuildDate>Wed, 31 Dec 2025 09:24:09 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://stackoverflow.max-everyday.com/wp-content/uploads/2017/02/max-stackoverflow-256.png</url>
	<title>kotlin &#8211; Max的程式語言筆記</title>
	<link>https://stackoverflow.max-everyday.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Kotlin 2.1.0 和 2.2.0 的主要差異</title>
		<link>https://stackoverflow.max-everyday.com/2025/12/kotlin-2-1-0-vs-2-2-0/</link>
					<comments>https://stackoverflow.max-everyday.com/2025/12/kotlin-2-1-0-vs-2-2-0/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Wed, 31 Dec 2025 09:24:08 +0000</pubDate>
				<category><![CDATA[Android筆記]]></category>
		<category><![CDATA[kotlin]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7598</guid>

					<description><![CDATA[Kotlin 2.1.0 和 2.2.0 的主要...]]></description>
										<content:encoded><![CDATA[
<p>Kotlin 2.1.0 和 2.2.0 的主要差異在於功能的「成熟度」與「編譯器規範」。</p>



<p>2.1.0 是許多新特性的試用期，而 2.2.0 則是將這些功能正式轉為穩定版，並加強了代碼規範的檢查。</p>



<h3 class="wp-block-heading">核心功能差異</h3>



<ul class="wp-block-list">
<li><strong>語法穩定化</strong>：在 2.1.0 還是預覽的功能，如 <code>when</code> 表達式中的 <code>guard</code> 條件（<code>when (x) { is String if x.isNotEmpty() -> ... }</code>）、非局部 <code>break</code> 與 <code>continue</code>、以及多個 <code>$</code> 符號的字串模板，在 2.2.0 都變成了正式穩定版。</li>



<li><strong>預設介面方法 (JVM)</strong>：2.2.0 改變了 JVM 上的編譯方式。現在介面中的預設方法會直接編譯成 Java 的 <code>default</code> 方法，不再產生額外的 <code>DefaultImpls</code> 類別，這讓 Kotlin 與 Java 的交互更自然，字節碼也更簡潔。</li>



<li><strong>標準庫加強</strong>：2.2.0 正式引入了穩定的 <code>Base64</code> 和 <code>HexFormat</code> API，以後處理編碼就不需要再找第三方函式庫或依賴特定平台。</li>



<li><strong>上下文參數 (Context Parameters)</strong>：2.2.0 引入了這個新功能的預覽版（取代舊的 context receivers），這對簡化依賴注入和提升代碼可讀性很有幫助。</li>
</ul>



<h3 class="wp-block-heading">Android 開發者的影響</h3>



<ul class="wp-block-list">
<li><strong>更嚴格的檢查</strong>：2.2.0 把很多 2.1.0 裡的警告提升到了錯誤級別。例如，如果你在 type aliases 裡用了不該用的 <code>reified</code> 修飾符，2.1.0 只會提醒你，2.2.0 會直接報錯不讓你編譯。</li>



<li><strong>記憶體優化</strong>：Kotlin/Native 在 2.2.0 針對 Apple 平台（iOS）有更細緻的記憶體分配管理，這對 KMP（Kotlin Multiplatform）專案很有感。</li>



<li><strong>編譯器警告管理</strong>：2.2.0 提供了統一的 <code>-Xwarning-level</code> 選項，讓你能更方便地控制專案中警告的顯示方式。</li>
</ul>



<h3 class="wp-block-heading">總結與建議</h3>



<p>如果你是新專案，直接上 <strong>2.2.0</strong> 比較好，因為它的標準庫更完整，語法也更穩定。</p>



<p>但如果是舊專案升級，從 2.1.0 升到 2.2.0 可能會遇到一些編譯報錯（因為 2.2.0 把一些舊的不良語法警告變成了錯誤），需要花點時間修正代碼。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>想了解具體的 <code>when</code> guard 語法範例，或是如何使用新的 Base64 API 嗎？</p>



<h3 class="wp-block-heading">when guard 語法範例</h3>



<p>這是 Kotlin 2.2.0 中最實用的新功能之一。它讓你在匹配類型的同時，可以直接加上額外的判斷條件，不需要在裡面多寫一層 if。</p>



<p>Kotlin</p>



<pre class="wp-block-code"><code>// 2.2.0 的寫法
when (response) {
    is Success if response.data.isEmpty() -&gt; println("成功但沒資料")
    is Success -&gt; println("拿到資料了")
    is Error if response.code == 404 -&gt; println("找不到頁面")
    else -&gt; println("其他錯誤")
}
</code></pre>



<p>在 2.1.0 以前，你必須寫成 <code>is Success -&gt; if (response.data.isEmpty()) ...</code>，程式碼層級會變得比較深。現在這樣寫更直覺，閱讀起來很像在讀英文句子。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Base64 API 範例</h3>



<p>以前在 Android 裡處理 Base64，我們通常會用到 <code>android.util.Base64</code>。但這會導致你的程式碼綁死在 Android 平台上。2.2.0 把這個功能放進了 Kotlin 標準庫。</p>



<pre class="wp-block-code"><code>import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi

@OptIn(ExperimentalEncodingApi::class)
fun testBase64() {
    val text = "Hello Kotlin 2.2"
    
    // 編碼
    val encoded = Base64.encode(text.encodeToByteArray())
    println(encoded)
    
    // 解碼
    val decodedBytes = Base64.decode(encoded)
    println(String(decodedBytes))
}
</code></pre>



<p>這對寫 KMP 跨平台專案的人來說是救星。你可以直接在 commonMain 資料夾裡寫編碼邏輯，不用再幫 iOS 和 Android 各自寫一套實作。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">開發建議</h3>



<p>如果你還在用 2.1.0，建議可以先在 build.gradle 試著改版號。如果出現很多紅色底線，通常是 2.2.0 對於語法規範變得更嚴格。</p>



<p>像是有些隱含的類型轉換或是不規範的泛型用法，2.2.0 都會要求你寫清楚。雖然修起來有點煩，但這能讓你的專案體質更健康，減少執行時期的閃退。</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2025/12/kotlin-2-1-0-vs-2-2-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AsyncTask migrate to Kotlin Coroutines</title>
		<link>https://stackoverflow.max-everyday.com/2025/12/asynctask-migrate-to-kotlin-coroutines/</link>
					<comments>https://stackoverflow.max-everyday.com/2025/12/asynctask-migrate-to-kotlin-coroutines/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 03:00:37 +0000</pubDate>
				<category><![CDATA[Android筆記]]></category>
		<category><![CDATA[kotlin]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7549</guid>

					<description><![CDATA[AsyncTask 已經在 Android AP...]]></description>
										<content:encoded><![CDATA[
<p>AsyncTask 已經在 Android API 30 正式廢棄。這不是隨意的決定，是因為它太容易造成內存洩漏，且生命週期管理混亂。</p>



<p>現在主流的替代方案是 Kotlin Coroutines 和 RxJava。</p>



<h3 class="wp-block-heading">核心比較與評估</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><td><strong>特性</strong></td><td><strong>Kotlin Coroutines</strong></td><td><strong>RxJava (RxAndroid)</strong></td></tr></thead><tbody><tr><td><strong>官方態度</strong></td><td>Google 官方首選，Jetpack 庫深度整合</td><td>成熟的第三方庫，處於維護期</td></tr><tr><td><strong>學習曲線</strong></td><td>較低，像在寫同步代碼</td><td>極高，需要理解各種操作符與流的概念</td></tr><tr><td><strong>代碼風格</strong></td><td>順序執行，簡潔明瞭</td><td>鏈式調用，容易變成「操作符地獄」</td></tr><tr><td><strong>內存佔用</strong></td><td>極輕量，支持暫停與恢復</td><td>較重，每個訂閱都會創建不少對象</td></tr><tr><td><strong>適用場景</strong></td><td>大多數 Android 開發、UI 交互、簡單請求</td><td>複雜的數據流、多個數據源頻繁組合、背壓處理</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Kotlin Coroutines：現代開發的首選</h3>



<p>如果你使用的是 Kotlin，這幾乎是不二之選。</p>



<p>它的優勢在於結構化並發（Structured Concurrency）。當你在 <code>ViewModel</code> 中使用 <code>viewModelScope.launch</code> 時，如果 <code>ViewModel</code> 銷毀，協程會自動取消。這直接解決了 AsyncTask 最頭痛的內存洩漏問題。</p>



<p>此外，它讓異步代碼看起來像同步代碼。你不需要寫回調，只需要在函數前加一個 <code>suspend</code> 關鍵字，就能在後台執行任務後直接更新 UI，邏輯非常直觀。</p>



<h3 class="wp-block-heading">RxJava：強大的流式處理工具</h3>



<p>RxJava 是一把沉重的重型武器。</p>



<p>如果你的應用需要處理非常複雜的數據流，例如：同時監聽傳感器、網絡狀態與用戶輸入，並將這三者實時組合處理，RxJava 的操作符（如 <code>combineLatest</code> 或 <code>zip</code>）會非常強大。</p>



<p>但在一般的開發場景中，RxJava 的維護成本較高。新人接手時，面對幾十行連在一起的操作符通常會感到崩潰。而且 RxJava 的錯誤處理比較瑣碎，一旦漏掉 <code>onError</code>，程序可能直接崩潰。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">遷移建議</h3>



<p><strong>如果你是從 AsyncTask 遷移：</strong></p>



<ul class="wp-block-list">
<li><strong>無腦選擇 Coroutines：</strong> 這是目前 Android 開發的標準。它能完美替代 <code>doInBackground</code>（對應 <code>withContext(Dispatchers.IO)</code>）和 <code>onPostExecute</code>（協程自動切回主線程）。</li>



<li><strong>考慮團隊成本：</strong> 協程的上手時間通常只要幾天，而 RxJava 可能需要幾週甚至幾個月才能熟練應用。</li>



<li><strong>庫的整合：</strong> 現在的 Retrofit、Room 等主流庫都已經原生支持 Coroutines，遷移阻力極小。</li>
</ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2025/12/asynctask-migrate-to-kotlin-coroutines/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>android AsyncTask 除了遷移至 Kotlin Coroutines, 可以改用  Runnable 或 Handler改寫?</title>
		<link>https://stackoverflow.max-everyday.com/2025/12/android-asynctask-runnable-handler/</link>
					<comments>https://stackoverflow.max-everyday.com/2025/12/android-asynctask-runnable-handler/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 02:58:40 +0000</pubDate>
				<category><![CDATA[Android筆記]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kotlin]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7550</guid>

					<description><![CDATA[替代方案的可行性 可以用 Runnable 搭配...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">替代方案的可行性</h3>



<p>可以用 Runnable 搭配 Handler 改寫。<br>這在協程普及前是很常見的做法。<br>原理是自己管理執行緒切換。<br>Runnable 負責定義要做的任務。<br>Handler 負責跨執行緒溝通。</p>



<h3 class="wp-block-heading">具體的執行方式</h3>



<p>你需要先準備一個 ExecutorService 執行緒池。<br>把耗時工作放進 Runnable 裡面。<br>透過 executor.execute 丟到背景執行。<br>當資料處理完畢。<br>再利用 Handler 的 post 方法切換回主執行緒。<br>這樣就能安全地更新介面元件。</p>



<pre class="wp-block-code"><code>ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());

executor.execute(new Runnable() {
    @Override
    public void run() {
        // 這裡跑背景任務
        final String data = "載入完成";

        handler.post(new Runnable() {
            @Override
            public void run() {
                // 這裡更新 UI
                textView.setText(data);
            }
        });
    }
});</code></pre>



<h3 class="wp-block-heading">優缺點評估</h3>



<p>這種做法控制權最高。<br>適合不支援 Kotlin 的老舊專案。<br>但是程式碼會變得很碎。<br>也要特別注意記憶體洩漏問題。<br>建議將 Handler 宣告為靜態類別。<br>才不會意外持有 Activity 的引用。<br>如果是簡單的任務。<br>這比導入整個協程庫還要輕量。</p>



<p>可以再利用 WeakReference 來優化這段程式碼以防止記憶體洩漏.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2025/12/android-asynctask-runnable-handler/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>kotlin 空安全處理是什麼?</title>
		<link>https://stackoverflow.max-everyday.com/2025/12/kotlin-null-safety/</link>
					<comments>https://stackoverflow.max-everyday.com/2025/12/kotlin-null-safety/#respond</comments>
		
		<dc:creator><![CDATA[max-stackoverflow]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 02:51:18 +0000</pubDate>
				<category><![CDATA[Android筆記]]></category>
		<category><![CDATA[kotlin]]></category>
		<guid isPermaLink="false">https://stackoverflow.max-everyday.com/?p=7546</guid>

					<description><![CDATA[Kotlin 的空安全（Null Safety）...]]></description>
										<content:encoded><![CDATA[
<p>Kotlin 的空安全（Null Safety）是為了根除 Java 最常見的 NullPointerException (NPE)。在 Kotlin 中，類型系統會強制區分「可以為空」和「不可以為空」的變量。</p>



<h3 class="wp-block-heading">可空類型與不可空類型</h3>



<p>在定義變量時，Kotlin 默認所有類型都是不可空的。如果你嘗試給它賦值 null，編譯器會直接報錯。</p>



<p>如果你希望一個變量可以存放 null，必須在類型後面加上問號。例如 <code>String</code> 不能為空，而 <code>String?</code> 則代表可以存放字符串或 null。</p>



<p>這種機制讓潛在的崩潰問題在編譯階段就被抓出來，而不是等到用戶使用時才發生。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">安全調用與強行轉換</h3>



<p>當你有一個可空變量時，你不能直接調用它的方法。你有幾種處理方式：</p>



<ol start="1" class="wp-block-list">
<li><strong>安全調用符 <code>?.</code></strong>：這是最常用的。如果變量是 null，調用會直接返回 null，而不會崩潰。</li>



<li><strong>非空斷言 <code>!!</code></strong>：如果你百分之百確定變量不為空，可以用這個。但如果猜錯了，程序會立刻崩潰。這通常是不建議的做法。</li>
</ol>



<h3 class="wp-block-heading">Elvis 運算符 <code>?:</code></h3>



<p>這個符號用來提供「默認值」。當左邊的表達式結果為 null 時，它會執行右邊的內容。</p>



<p>這在處理 UI 顯示時非常好用，比如 <code>val name = user?.name ?: "匿名用戶"</code>。如果用戶數據不存在，就會直接顯示默認稱呼。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">類型轉換與檢查</h3>



<p>Kotlin 會自動進行類型轉換（Smart Cast）。如果你已經用 <code>if</code> 檢查過變量不為空，在該代碼塊範圍內，你可以直接把它當成不可空類型來用，不需要再寫問號。</p>



<p>這讓代碼保持乾淨，同時又具備極高的安全性。這就像是在寫代碼前加了一層過濾網，過濾掉所有可能讓程序當機的空指針。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://stackoverflow.max-everyday.com/2025/12/kotlin-null-safety/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
