You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin仅用函数封装传递数据的更优实现方案问询

仅用函数封装Person数据的优化方案咨询

出于兴趣用Kotlin开展编程实验,目标为仅通过函数(禁止使用类与数据类)封装并传递数据,已完成一种基于函数构造器的Person数据存储实现,代码如下:

// I've created a function structure that allows me to keep data of a "Person" in memory:
package org.example

typealias InvocableParameter = (String) -> (() -> Any?)?

fun personConstructor(
    name: String,
    age: Int,
    mother: InvocableParameter = { null }): InvocableParameter {
    return { parameter: String ->
        when (parameter) {
            "name" ->
                { name }
            "age" ->
                { age }
            "mother" ->
                { mother }
            "toJson" ->
                { "{ \"name\": \"$name\", \"age\": $age }" }
            else ->
                null
        }
    }
}

fun main() {
    val johnObject = personConstructor(
        "john", 20,
        personConstructor(
            "Lory", 40,
            personConstructor("Eva", 60)
        )
    )
    println(johnObject("toJson")?.invoke())
    val johnsMother = johnObject("mother")?.invoke() as InvocableParameter
    val johnsGrandma = (johnsMother.invoke("mother")?.invoke()) as InvocableParameter
    println(johnsMother.invoke("toJson")?.invoke())
    println(johnsGrandma.invoke("toJson")?.invoke())
}

// Outputs:
// { "name": "john", "age": 20 }
// { "name": "Lory", "age": 40 }
// { "name": "Eva", 60 }

现咨询是否有更简洁优雅的实现方式达成该目标。


优化后的实现方案

可以从简化类型定义、减少冗余调用、提升可读性与类型安全性几个方向优化,以下是几种更简洁的实现思路:

1. 简化核心类型与访问逻辑

原实现的嵌套函数调用冗余度高,可将类型简化为直接返回值的函数,避免额外的invoke()调用:

package org.example

typealias Person = (String) -> Any?

fun person(
    name: String,
    age: Int,
    mother: Person = { null }
): Person = { key ->
    when (key) {
        "name" -> name
        "age" -> age
        "mother" -> mother
        "toJson" -> """{"name": "$name", "age": $age}"""
        else -> null
    }
}

fun main() {
    val john = person(
        "john", 20,
        person("Lory", 40, person("Eva", 60))
    )
    println(john("toJson"))
    val johnsMother = john("mother") as Person
    val johnsGrandma = johnsMother("mother") as Person
    println(johnsMother("toJson"))
    println(johnsGrandma("toJson"))
}

关键优化:

  • 将类型别名重命名为语义化的Person,提升可读性
  • 直接返回属性值而非嵌套无参函数,访问时无需额外?.invoke()
  • 使用Kotlin三重引号简化JSON字符串的转义操作

2. 基于映射的可扩展实现

如果需要新增属性,可将属性映射逻辑提取到Map中,避免修改when分支,提升扩展性:

package org.example

typealias Person = (String) -> Any?

fun person(
    name: String,
    age: Int,
    mother: Person = { null }
): Person {
    val props = mapOf(
        "name" to name,
        "age" to age,
        "mother" to mother,
        "toJson" to """{"name": "$name", "age": $age}"""
    )
    return { props[it] }
}

// 调用逻辑与上述main函数一致

这种方式下,新增属性只需在props中添加键值对即可,无需改动核心逻辑。

3. 类型安全的访问封装

为避免频繁的强制类型转换,可封装泛型访问函数,提升类型安全性与代码简洁度:

package org.example

typealias Person = (String) -> Any?

fun person(
    name: String,
    age: Int,
    mother: Person = { null }
): Person = { key ->
    when (key) {
        "name" -> name
        "age" -> age
        "mother" -> mother
        "toJson" -> """{"name": "$name", "age": $age}"""
        else -> null
    }
}

inline fun <reified T> Person.get(key: String): T? = this(key) as? T

fun main() {
    val john = person(
        "john", 20,
        person("Lory", 40, person("Eva", 60))
    )
    println(john.get<String>("toJson"))
    
    val johnsMother = john.get<Person>("mother")
    val johnsGrandma = johnsMother?.get<Person>("mother")
    
    println(johnsMother?.get<String>("toJson"))
    println(johnsGrandma?.get<String>("toJson"))
}

关键优化:

  • 通过泛型函数get封装类型转换,避免直接as强制转换,减少类型转换异常风险
  • 调用时通过get<String>或get<Person>明确类型,代码可读性更强

以上方案均严格遵循"仅用函数封装数据"的要求,同时在简洁性、可读性与扩展性上有明显提升。

内容的提问来源于stack exchange,提问作者Arthur Frade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:05:54