在这里插入图片描述

目录

  1. 概述
  2. 算法功能
  3. 核心实现
  4. 实战案例
  5. 编译过程详解
  6. 算法扩展
  7. 最佳实践
  8. 常见问题

概述

本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的URL编码解码算法系统。这个案例展示了如何使用 Kotlin 的字符串操作、正则表达式和编码转换来创建一个功能丰富的文本编码工具。通过 KMP,这个算法可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,并支持用户输入进行实时转换。

算法的特点

  • 多种编码格式:支持 URL 编码和 Base64 编码
  • 自动检测:自动识别输入是否为编码文本
  • 双向转换:支持编码和解码
  • 详细统计:提供字符统计和分析
  • 跨端兼容:一份 Kotlin 代码可同时服务多个平台

算法功能

1. URL编码

  • 编码规则:将特殊字符转换为 %XX 格式
  • 保留字符:字母、数字、-_.~ 不编码
  • 特殊字符:空格、&、=、? 等转换为 %XX

2. URL解码

  • 解码规则:将 %XX 转换回原始字符
  • 自动检测:识别是否为 URL 编码文本
  • 错误处理:处理无效的编码序列

3. Base64编码

  • 编码规则:将文本转换为 Base64 格式
  • 字符集:使用标准 Base64 字符集
  • 填充:使用 = 进行填充

4. 字符统计

  • 字母数:统计字母个数
  • 数字数:统计数字个数
  • 空格数:统计空格个数
  • 特殊字符:统计特殊字符种类

5. 编码对比

  • 长度对比:比较原始文本和编码后的长度
  • 增长率:计算编码后的增长百分比
  • 多种格式:显示不同编码格式的结果

核心实现

1. URL编码

val encoded = inputText
    .map { char ->
        when {
            char.isLetterOrDigit() || char in "-_.~" -> char.toString()
            else -> "%${char.code.toString(16).uppercase().padStart(2, '0')}"
        }
    }
    .joinToString("")

代码说明:

这段代码实现了 URL 编码功能。对输入文本中的每个字符进行处理:如果字符是字母、数字或特殊字符 -_.~(这些是 URL 中的安全字符),则保持原样;否则将其转换为 % 后跟两位十六进制数字的格式。例如,空格字符会被编码为 %20,中文字符会被编码为其 UTF-8 字节的十六进制表示。map() 函数对每个字符进行转换,joinToString("") 将转换后的字符连接成一个字符串。

2. URL解码

val decoded = try {
    var result = inputText
    val pattern = Regex("%([0-9A-Fa-f]{2})")
    result = pattern.replace(result) { matchResult ->
        val hex = matchResult.groupValues[1]
        hex.toInt(16).toChar().toString()
    }
    result
} catch (e: Exception) {
    "解码失败"
}

代码说明:

这段代码实现了 URL 解码功能。使用正则表达式 %([0-9A-Fa-f]{2}) 来匹配 % 后跟两位十六进制数字的模式。对于每个匹配,提取十六进制数字部分,使用 toInt(16) 将其转换为十进制数字,然后使用 toChar() 转换为对应的字符。例如,%20 会被解码为空格字符。整个过程被包裹在 try-catch 块中,如果解码过程中出现任何异常,返回错误信息。

3. 编码类型检测

val isEncoded = inputText.contains("%") && inputText.contains(Regex("%[0-9A-Fa-f]{2}"))

代码说明:

这段代码用于检测输入的文本是否为 URL 编码格式。使用两个条件的逻辑与操作:首先检查文本是否包含百分号 %,然后使用正则表达式检查是否包含 % 后跟两位十六进制数字的模式。只有当两个条件都满足时,才认为输入是 URL 编码文本。这种检测方法可以有效地区分普通文本和编码文本,避免对普通文本进行不必要的解码操作。

4. Base64编码

val base64Encoded = try {
    val base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    val result = StringBuilder()
    val chars = inputText.toList()
    var i = 0
    while (i < chars.size) {
        val b1 = chars[i].code
        val b2 = if (i + 1 < chars.size) chars[i + 1].code else 0
        val b3 = if (i + 2 < chars.size) chars[i + 2].code else 0
        
        val enc1 = b1 shr 2
        val enc2 = ((b1 and 0x03) shl 4) or (b2 shr 4)
        val enc3 = ((b2 and 0x0F) shl 2) or (b3 shr 6)
        val enc4 = b3 and 0x3F
        
        result.append(base64Chars[enc1 and 0x3F])
        result.append(base64Chars[enc2 and 0x3F])
        result.append(if (i + 1 < chars.size) base64Chars[enc3 and 0x3F] else '=')
        result.append(if (i + 2 < chars.size) base64Chars[enc4 and 0x3F] else '=')
        
        i += 3
    }
    result.toString()
} catch (e: Exception) {
    "编码失败"
}

代码说明:

这段代码实现了 Base64 编码功能。Base64 编码将输入文本分成 3 字节一组进行处理,每组 3 字节(24 位)转换为 4 个 Base64 字符(每个字符 6 位)。首先定义 Base64 字符集,包含 26 个大写字母、26 个小写字母、10 个数字和 2 个特殊字符。然后逐组处理输入字符,每次读取 3 个字符的 ASCII 码。使用位运算提取每个 6 位的编码值:enc1 是第一个字节的高 6 位,enc2 是第一个字节的低 2 位加第二个字节的高 4 位,enc3 是第二个字节的低 4 位加第三个字节的高 2 位,enc4 是第三个字节的低 6 位。最后根据实际字符数添加相应的 Base64 字符或填充符 =。整个过程被包裹在 try-catch 块中以处理异常。

5. 字符统计

val letterCount = inputText.count { it.isLetter() }
val digitCount = inputText.count { it.isDigit() }
val spaceCount = inputText.count { it == ' ' }
val specialChars = inputText.filter { !it.isLetterOrDigit() && it != ' ' }.toSet()

代码说明:

这段代码统计输入文本中各种类型字符的数量。使用 count() 函数对文本进行逐字符扫描,统计满足特定条件的字符数量。letterCount 统计所有字母字符,digitCount 统计所有数字字符,spaceCount 统计所有空格字符。最后使用 filter() 提取所有既不是字母也不是数字也不是空格的字符(即特殊字符),然后转换为 Set 以去重,得到特殊字符的种类。这些统计信息可以用于分析文本的组成,帮助用户了解输入文本的特征。


实战案例

案例:完整的URL编码解码算法

Kotlin 源代码

代码说明:

这是 URL 编码解码工具的完整 Kotlin 实现,使用 @JsExport 装饰器将其导出为 JavaScript 可调用的函数。函数接收一个输入字符串,默认值为包含特殊字符的示例文本。函数执行多个步骤:首先进行输入验证,检查输入是否为空。然后进行 URL 编码,将特殊字符转换为 %XX 格式。接着检测输入是否已经是 URL 编码格式,如果是则进行解码。同时进行 Base64 编码。最后统计输入文本的各种字符类型,计算编码前后的大小变化,并生成详细的分析报告。函数返回一个格式化的结果字符串,包含所有编码结果和统计信息。

@OptIn(ExperimentalJsExport::class)
@JsExport
fun urlEncodingDecoder(inputText: String = "Hello World & Special Chars!"): String {
    if (inputText.isEmpty()) {
        return "❌ 错误: 输入不能为空\n请输入要编码或解码的文本"
    }
    
    // 1. URL编码
    val encoded = inputText
        .map { char ->
            when {
                char.isLetterOrDigit() || char in "-_.~" -> char.toString()
                else -> "%${char.code.toString(16).uppercase().padStart(2, '0')}"
            }
        }
        .joinToString("")
    
    // 2. 分析输入类型
    val isEncoded = inputText.contains("%") && inputText.contains(Regex("%[0-9A-Fa-f]{2}"))
    
    // 3. URL解码
    val decoded = if (isEncoded) {
        try {
            var result = inputText
            val pattern = Regex("%([0-9A-Fa-f]{2})")
            result = pattern.replace(result) { matchResult ->
                val hex = matchResult.groupValues[1]
                hex.toInt(16).toChar().toString()
            }
            result
        } catch (e: Exception) {
            "解码失败"
        }
    } else {
        inputText
    }
    
    // 4. Base64编码
    val base64Encoded = try {
        val base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        val result = StringBuilder()
        val chars = inputText.toList()
        var i = 0
        while (i < chars.size) {
            val b1 = chars[i].code
            val b2 = if (i + 1 < chars.size) chars[i + 1].code else 0
            val b3 = if (i + 2 < chars.size) chars[i + 2].code else 0
            
            val enc1 = b1 shr 2
            val enc2 = ((b1 and 0x03) shl 4) or (b2 shr 4)
            val enc3 = ((b2 and 0x0F) shl 2) or (b3 shr 6)
            val enc4 = b3 and 0x3F
            
            result.append(base64Chars[enc1 and 0x3F])
            result.append(base64Chars[enc2 and 0x3F])
            result.append(if (i + 1 < chars.size) base64Chars[enc3 and 0x3F] else '=')
            result.append(if (i + 2 < chars.size) base64Chars[enc4 and 0x3F] else '=')
            
            i += 3
        }
        result.toString()
    } catch (e: Exception) {
        "编码失败"
    }
    
    // 5. 统计信息
    val originalLength = inputText.length
    val encodedLength = encoded.length
    val compressionRatio = if (originalLength > 0) 
        ((encodedLength - originalLength) * 100 / originalLength) else 0
    
    // 6. 特殊字符统计
    val specialChars = inputText.filter { !it.isLetterOrDigit() && it != ' ' }.toSet()
    val specialCharCount = specialChars.size
    
    // 7. 字符类型统计
    val letterCount = inputText.count { it.isLetter() }
    val digitCount = inputText.count { it.isDigit() }
    val spaceCount = inputText.count { it == ' ' }
    val otherCount = inputText.length - letterCount - digitCount - spaceCount
    
    return "🔗 URL编码解码工具\n" +
           "━━━━━━━━━━━━━━━━━━━━━\n" +
           "原始文本: $inputText\n" +
           "文本长度: $originalLength 个字符\n\n" +
           "1️⃣ 编码结果:\n" +
           "  URL编码: $encoded\n" +
           "  编码长度: $encodedLength 个字符\n" +
           "  增长率: +$compressionRatio%\n\n" +
           "2️⃣ Base64编码:\n" +
           "  $base64Encoded\n\n" +
           "3️⃣ 字符统计:\n" +
           "  字母: $letterCount 个\n" +
           "  数字: $digitCount 个\n" +
           "  空格: $spaceCount 个\n" +
           "  其他: $otherCount 个\n" +
           "  特殊字符种类: $specialCharCount 种\n\n" +
           "4️⃣ 特殊字符:\n" +
           (if (specialChars.isEmpty()) "  无特殊字符" else "  ${specialChars.joinToString(", ")}") +
           "\n\n" +
           "5️⃣ 输入类型检测:\n" +
           "  是否为URL编码: ${if (isEncoded) "✅ 是" else "❌ 否"}\n" +
           (if (isEncoded) "  解码结果: $decoded\n" else "") +
           "\n" +
           "━━━━━━━━━━━━━━━━━━━━━\n" +
           "✅ 转换完成!"
}
ArkTS 调用代码(带输入框)

代码说明:

这是 OpenHarmony ArkTS 页面的完整实现,展示了如何集成和调用 Kotlin 编译生成的 URL 编码解码函数。首先通过 import 语句从 ./hellokjs 模块导入 urlEncodingDecoder 函数。页面使用 @Entry@Component 装饰器定义为可入口的组件。定义了四个响应式状态变量:message 显示操作状态,results 存储编码结果,caseTitle 显示标题,inputText 存储用户输入的文本。aboutToAppear() 生命周期钩子在页面加载时调用 loadResults() 进行初始化。loadResults() 方法调用 Kotlin 函数进行编码和解码,并将结果存储在 results 数组中。build() 方法定义了完整的 UI 布局,包括顶部标题栏、输入框、转换按钮、结果展示区域和底部操作按钮,使用了 Column、Row、Text、TextInput、Button 等组件构建了一个功能完整的用户界面。

import { urlEncodingDecoder } from './hellokjs';

@Entry
@Component
struct Index {
  @State message: string = '加载中...';
  @State results: string[] = [];
  @State caseTitle: string = 'URL编码解码工具';
  @State inputText: string = 'Hello World & Special Chars!';

  aboutToAppear(): void {
    this.loadResults();
  }

  loadResults(): void {
    try {
      const results: string[] = [];
      const algorithmResult = urlEncodingDecoder(this.inputText);
      results.push(algorithmResult);
      
      this.results = results;
      this.message = '✓ 转换完成';
    } catch (error) {
      this.message = `✗ 错误: ${error}`;
    }
  }

  build() {
    Column() {
      // 顶部标题栏
      Row() {
        Text('KMP 鸿蒙跨端')
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
        Spacer()
        Text('Kotlin 案例')
          .fontSize(14)
          .fontColor(Color.White)
      }
      .width('100%')
      .height(50)
      .backgroundColor('#3b82f6')
      .padding({ left: 20, right: 20 })
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.SpaceBetween)

      // 案例标题
      Column() {
        Text(this.caseTitle)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#1f2937')
        Text(this.message)
          .fontSize(13)
          .fontColor('#6b7280')
          .margin({ top: 5 })
      }
      .width('100%')
      .padding({ left: 20, right: 20, top: 20, bottom: 15 })
      .alignItems(HorizontalAlign.Start)

      // 输入框区域
      Column() {
        Text('输入文本:')
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .fontColor('#1f2937')
          .margin({ bottom: 8 })
        
        TextInput({ placeholder: '输入要编码的文本...', text: this.inputText })
          .width('100%')
          .height(60)
          .padding(12)
          .border({ width: 1, color: '#d1d5db' })
          .borderRadius(6)
          .onChange((value: string) => {
            this.inputText = value
          })
        
        Button('转换')
          .width('100%')
          .height(40)
          .margin({ top: 12 })
          .backgroundColor('#3b82f6')
          .fontColor(Color.White)
          .onClick(() => {
            this.loadResults()
          })
      }
      .width('100%')
      .padding({ left: 16, right: 16, bottom: 16 })

      // 结果显示区域
      Scroll() {
        Column() {
          ForEach(this.results, (result: string) => {
            Column() {
              Text(result)
                .fontSize(13)
                .fontFamily('monospace')
                .fontColor('#374151')
                .width('100%')
                .margin({ top: 10 })
            }
            .width('100%')
            .padding(16)
            .backgroundColor(Color.White)
            .border({ width: 1, color: '#e5e7eb' })
            .borderRadius(8)
            .margin({ bottom: 12 })
          })
        }
        .width('100%')
        .padding({ left: 16, right: 16 })
      }
      .layoutWeight(1)
      .width('100%')

      // 底部按钮区域
      Row() {
        Button('示例文本')
          .width('48%')
          .height(44)
          .backgroundColor('#10b981')
          .fontColor(Color.White)
          .fontSize(14)
          .onClick(() => {
            this.inputText = 'Hello World & Special Chars!'
            this.loadResults()
          })

        Button('清空')
          .width('48%')
          .height(44)
          .backgroundColor('#6b7280')
          .fontColor(Color.White)
          .fontSize(14)
          .onClick(() => {
            this.inputText = ''
            this.results = []
          })
      }
      .width('100%')
      .padding({ left: 16, right: 16, bottom: 20 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f9fafb')
  }
}

编译过程详解

Kotlin 到 JavaScript 的转换

Kotlin 特性 JavaScript 等价物
map() 数组 map 方法
joinToString() 数组 join 方法
Regex.replace() 字符串 replace 方法
toInt(16) parseInt(str, 16)
count() 条件计数循环
filter() 数组 filter 方法

关键转换点

  1. 字符编码:转换为 JavaScript 字符编码
  2. 正则表达式:转换为 JavaScript RegExp
  3. 集合操作:转换为数组操作
  4. 字符串处理:保持功能一致

算法扩展

扩展 1:添加 Hex 编码

fun hexEncode(text: String): String {
    return text.map { char ->
        char.code.toString(16).uppercase().padStart(2, '0')
    }.joinToString(" ")
}

代码说明:

这个函数实现了十六进制编码功能。对输入文本中的每个字符进行处理:首先获取字符的 ASCII 码,使用 toString(16) 将其转换为十六进制字符串,然后使用 uppercase() 转换为大写,最后使用 padStart(2, '0') 确保结果是两位数字(不足时左边补 0)。例如,字符 ‘A’ 的 ASCII 码是 65,转换为十六进制是 “41”。最后使用 joinToString(" ") 将所有十六进制值用空格连接。这种编码方式常用于调试和数据分析。

扩展 2:添加 HTML 实体编码

fun htmlEntityEncode(text: String): String {
    return text.replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace("\"", "&quot;")
        .replace("'", "&#39;")
}

代码说明:

这个函数实现了 HTML 实体编码功能,用于在 HTML 中安全地显示特殊字符。函数使用链式 replace() 调用,将特殊字符替换为对应的 HTML 实体。例如,& 替换为 &amp;< 替换为 &lt;> 替换为 &gt;,双引号替换为 &quot;,单引号替换为 &#39;。这种编码方式防止了 HTML 注入攻击,确保用户输入的特殊字符在网页中正确显示,而不会被解析为 HTML 标签。

扩展 3:添加 Unicode 编码

fun unicodeEncode(text: String): String {
    return text.map { char ->
        "\\u${char.code.toString(16).uppercase().padStart(4, '0')}"
    }.joinToString("")
}

代码说明:

这个函数实现了 Unicode 编码功能,将文本中的每个字符转换为 Unicode 转义序列。对输入文本中的每个字符进行处理:首先获取字符的 Unicode 码点,使用 toString(16) 将其转换为十六进制字符串,然后使用 uppercase() 转换为大写,最后使用 padStart(4, '0') 确保结果是四位数字(不足时左边补 0)。例如,字符 ‘A’ 的 Unicode 码点是 65,转换为 Unicode 转义序列是 \u0041。最后使用 joinToString("") 将所有转义序列连接。这种编码方式常用于处理多语言文本和特殊字符。

扩展 4:添加 Punycode 编码

fun punycodeEncode(domain: String): String {
    // Punycode 编码实现
    return "xn--" + domain.map { it.code }.joinToString("")
}

代码说明:

这个函数展示了如何实现 Punycode 编码,用于将国际化域名(IDN)转换为 ASCII 兼容的编码形式。Punycode 是一种编码方式,允许在 DNS 系统中使用非 ASCII 字符。函数首先添加 “xn–” 前缀,这是 Punycode 编码的标准前缀。然后对域名中的每个字符获取其 Unicode 码点,并将这些码点连接成一个字符串。这是一个简化的实现,完整的 Punycode 编码算法更加复杂,需要处理多种情况和优化。这种编码方式使得国际化域名可以在全球互联网中使用。


最佳实践

1. 使用 map() 进行字符转换

// ✅ 好:使用 map()
val encoded = text.map { char -> /* 转换逻辑 */ }.joinToString("")

// ❌ 不好:使用 for 循环
val encoded = StringBuilder()
for (char in text) {
    encoded.append(/* 转换逻辑 */)
}

代码说明:

这个示例对比了两种字符转换的方法。第一种方法使用 map() 函数,代码简洁易读,函数式风格更符合 Kotlin 的设计理念。map() 对每个字符进行转换,然后使用 joinToString("") 将结果连接成字符串。第二种方法使用 for 循环和 StringBuilder,虽然也能实现相同的功能,但代码更冗长。两种方法的性能基本相同,但 map() 方法更加简洁优雅。最佳实践是在进行集合转换时优先使用 map() 等函数式方法。

2. 使用正则表达式进行替换

// ✅ 好:使用 Regex.replace()
val decoded = Regex("%([0-9A-Fa-f]{2})").replace(text) { /* 替换逻辑 */ }

// ❌ 不好:手动查找替换
var result = text
while (result.contains("%")) {
    // 复杂的替换逻辑
}

代码说明:

这个示例对比了两种进行复杂替换的方法。第一种方法使用 Regex.replace() 和 lambda 表达式,能够高效地处理复杂的替换逻辑。正则表达式可以精确匹配要替换的模式,lambda 表达式可以对每个匹配进行自定义处理。第二种方法使用 while 循环和手动查找替换,代码复杂且容易出错,特别是在处理复杂模式时。最佳实践是在进行复杂替换时使用正则表达式。

3. 使用 count() 统计

// ✅ 好:使用 count()
val letterCount = text.count { it.isLetter() }

// ❌ 不好:使用 filter().size
val letterCount = text.filter { it.isLetter() }.size

代码说明:

这个示例对比了两种统计字符数量的方法。第一种方法使用 count() 函数,它直接遍历字符串并计算满足条件的字符数量,效率更高,因为它只需要一次遍历。第二种方法先使用 filter() 创建一个包含所有匹配字符的新列表,然后获取这个列表的大小,这会产生额外的内存开销和两次遍历。对于大型文本,使用 count() 的性能优势会更加明显。最佳实践是优先使用 count() 来进行统计操作。

4. 错误处理

// ✅ 好:使用 try-catch
val result = try {
    /* 编码逻辑 */
} catch (e: Exception) {
    "编码失败"
}

// ❌ 不好:忽略异常
val result = /* 编码逻辑 */

代码说明:

这个示例对比了两种处理异常的方法。第一种方法使用 try-catch 块来捕获可能发生的异常,并返回一个有意义的错误信息。这种方法能够优雅地处理错误,防止程序崩溃,并为用户提供有用的反馈。第二种方法忽略异常,如果编码逻辑出现错误会导致程序崩溃或产生不可预测的结果。最佳实践是在处理可能出错的操作时始终使用 try-catch 块,并提供有意义的错误信息。


常见问题

Q1: 如何处理 Unicode 字符?

A: Kotlin 原生支持 Unicode:

val text = "你好世界 🌍"
val encoded = text.map { char ->
    "%${char.code.toString(16).uppercase().padStart(2, '0')}"
}.joinToString("")

代码说明:

这段代码展示了如何处理包含 Unicode 字符的文本。Kotlin 原生支持 Unicode,可以直接处理中文、emoji 等多语言字符。代码对每个字符(包括 Unicode 字符)进行 URL 编码,获取字符的 Unicode 码点,转换为十六进制,然后格式化为 %XX 的形式。例如,中文字符"你"的 Unicode 码点是 20320,转换为十六进制是 4F60,编码后是 %4F%60。这种方法可以正确处理任何 Unicode 字符。

Q2: 如何实现 HTML 实体编码?

A: 使用 replace 方法:

fun htmlEntityEncode(text: String): String {
    return text.replace("&", "&amp;")
        .replace("<", "&lt;")
        .replace(">", "&gt;")
        .replace("\"", "&quot;")
}

代码说明:

这段代码展示了如何实现 HTML 实体编码。使用链式 replace() 调用,将 HTML 中的特殊字符替换为对应的实体。& 替换为 &amp;< 替换为 &lt;> 替换为 &gt;" 替换为 &quot;。这种编码方式防止了 HTML 注入攻击,确保用户输入的特殊字符在网页中正确显示。链式调用的顺序很重要,应该先替换 &,否则会对后续的替换结果进行二次替换。

Q3: 如何检测编码类型?

A: 使用正则表达式检测:

val isUrlEncoded = text.contains(Regex("%[0-9A-Fa-f]{2}"))
val isBase64 = text.matches(Regex("[A-Za-z0-9+/]*={0,2}"))
val isHtmlEntity = text.contains(Regex("&[a-z]+;"))

代码说明:

这段代码展示了如何使用正则表达式检测不同的编码类型。isUrlEncoded 检查文本是否包含 URL 编码的模式(%XX 格式)。isBase64 检查文本是否匹配 Base64 格式(只包含字母、数字、+、/ 和最多两个 = 填充符)。isHtmlEntity 检查文本是否包含 HTML 实体的模式(&name; 格式)。这些检测可以帮助自动识别输入文本的编码格式,从而选择合适的解码方法。

Q4: 如何处理特殊字符?

A: 使用 when 表达式:

val encoded = text.map { char ->
    when {
        char.isLetterOrDigit() -> char.toString()
        char in "-_.~" -> char.toString()
        else -> "%${char.code.toString(16).uppercase().padStart(2, '0')}"
    }
}.joinToString("")

代码说明:

这段代码展示了如何使用 when 表达式处理特殊字符。对每个字符进行分类处理:如果是字母或数字,保持原样。如果是 URL 安全字符(-_.~),也保持原样。其他所有字符都进行 URL 编码,转换为 %XX 格式。这种方法遵循 RFC 3986 标准,确保编码的 URL 在各种系统中都能正确解析。

Q5: 如何优化性能?

A: 使用 StringBuilder 而不是字符串连接:

val result = StringBuilder()
for (char in text) {
    result.append(/* 转换逻辑 */)
}
result.toString()

代码说明:

这段代码展示了如何优化字符串构建的性能。使用 StringBuilder 而不是字符串连接操作符 +StringBuilder 是专门为高效字符串构建设计的可变字符序列,每次调用 append() 都直接添加字符到内部缓冲区。而字符串连接操作符在每次迭代中都会创建一个新的字符串对象,因为 Kotlin 中的字符串是不可变的。对于大型文本,使用 StringBuilder 的性能可以提高数倍。这是处理大量字符串操作时的最佳实践。


总结

关键要点

  • ✅ 使用 map() 进行字符转换
  • ✅ 使用正则表达式进行复杂替换
  • ✅ 使用 count() 进行统计
  • ✅ 实现自动类型检测
  • ✅ KMP 能无缝编译到 JavaScript
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐