如何为不同Kotlin目标平台编写差异化代码?
Kotlin多平台:JS与Native平台的代码隔离方案
完全可以实现,Kotlin多平台原生支持两种核心方式来区分JS和Native平台的代码,正好对应你提到的类内嵌入代码和多版本文件两种场景:
1. 条件编译(类内嵌入平台专属代码)
你说的类似#if js的语法是支持的,不过要注意平台标识是大写的:JS和NATIVE,可以在同一个文件或函数内嵌入不同平台的代码片段:
fun handlePlatformTask() { #if JS // JS平台专属逻辑:比如直接调用JS API js("alert('JS平台执行')") #elseif NATIVE // Native平台专属逻辑:比如调用C交互代码 println("Native平台执行") #endif }
如果是更复杂的类或接口差异,推荐用expect/actual模式,这是Kotlin多平台的标准写法:
// 通用模块定义抽象接口 expect class PlatformService { fun getEnvironmentInfo(): String } // JS平台实现(放在jsMain源集) actual class PlatformService { actual fun getEnvironmentInfo() = "JS Runtime: ${js("navigator.userAgent")}" } // Native平台实现(放在nativeMain源集) actual class PlatformService { actual fun getEnvironmentInfo() = "Native OS: ${Platform.osFamily.name}" }
2. 多版本文件(按平台后缀区分)
Kotlin支持通过文件名后缀指定平台专属文件,比如你说的SomeClass.js.kt和SomeClass.native.kt:
- 命名规则:文件名格式为
[文件名].[平台标识].kt,JS用js,通用Native用native,如果是Native子平台(如iOS、macOS)可以用ios、macos等更具体的标识。 - 编译时,Kotlin会自动根据当前目标平台选择对应的文件版本,不带后缀的
SomeClass.kt会作为通用代码被所有平台共享。 - 示例:
NetworkClient.js.kt:仅JS编译时生效,实现基于Fetch的网络请求NetworkClient.native.kt:仅Native编译时生效,实现基于原生网络库的请求
关键注意点
- 条件编译的平台标识必须大写:
JS、NATIVE、JVM,写错大小写会导致指令失效。 expect/actual模式比直接条件编译更易维护,适合大型项目的平台差异逻辑;条件编译适合小范围的代码片段差异。- 用Gradle构建时无需额外配置,平台后缀文件会自动被归类到对应的源集(jsMain、nativeMain等)。
内容的提问来源于stack exchange,提问作者singpolyma
相关产品推荐
相关产品推荐

