Java 中可以做到函数嵌套吗

23 小时 43 分钟前
 DIO

我知道可以通过 Runnable 来让 lambda 前置并在后面调用,而且最终实际上是通过包装成私有函数运行,不会有额外开销。但是有没有办法让子函数体后置,业务代码在前?

函数式编程貌似可以做到。Java 中有没有办法呢。

至于为什么不用 kt ,嗯,公司业务积重难返了。


function parentFunction() {
    // 业务代码部分
    const data = [1, 2, 3, 4, 5];
    
    const doubled = doubleData(data);
    console.log('Doubled Data:', doubled);
    
    const filtered = filterData(doubled, isEven);
    console.log('Filtered Data (Even):', filtered);
    
    // 子函数定义部分
    function doubleData(arr) {
        return arr.map(function(num) {
            return multiply(num, 2);
        });
    }

    function multiply(a, b) {
        return a * b;
    }

    function filterData(arr, predicate) {
        const result = [];
        for (let i = 0; i < arr.length; i++) {
            if (predicate(arr[i])) {
                result.push(arr[i]);
            }
        }
        return result;
    }

    function isEven(num) {
        return num % 2 === 0;
    }
}


fun parentFunction() {
    // 业务代码部分
    val data = listOf(1, 2, 3, 4, 5)
    
    val doubled = doubleData(data)
    println("Doubled Data: $doubled")
    
    val filtered = filterData(doubled, ::isEven)
    println("Filtered Data (Even): $filtered")

    // 子函数定义部分
    fun doubleData(arr: List<Int>): List<Int> {
        return arr.map { multiply(it, 2) }
    }

    fun multiply(a: Int, b: Int): Int {
        return a * b
    }

    fun filterData(arr: List<Int>, predicate: (Int) -> Boolean): List<Int> {
        return arr.filter(predicate)
    }

    fun isEven(num: Int): Boolean {
        return num % 2 == 0
    }
}

2744 次点击
所在节点    Android
31 条回复
iPisces77
23 小时 39 分钟前
不支持,java 所有方法要么放在类里,要么放在接口里
cpstar
23 小时 31 分钟前
可以匿名类+继承/实现的方法
kapaseker
23 小时 25 分钟前
没有特别明白你说的啥,但是 Java 我记得也支持 lambda 表达式以及 this::someMethod 这种写法啊。还是说你就是希望像 Kotlin 那样,编写 aabb {} 代码?
lisongeee
23 小时 20 分钟前
你的 js 能运行是因为 function 有变量提升,你换成 const 就不行了而且会报错

此外如果你在函数里访问了外部 const 变量但是此时 const 变量还未初始化,也会报错
qW7bo2FbzbC0
23 小时 7 分钟前
@kapaseker lamda 我记得也是生成匿名类把这个方法附加上去?楼主说的这种,纯 OOP 风格的语言应该有点难度
justdoit123
23 小时 6 分钟前
个人实在不喜欢函数里声明大量函数的做法。

感觉一打开一个函数,就要先面对大量的“子函数”实现细节,然后才能看到函数本身的逻辑,这个跟你提问的苦恼一样。我感觉组织这种逻辑,还是 class 最适合。
wolfie
23 小时 6 分钟前
Why ???
同一个 class 下 定义 private method 不行吗?
必须 method 级别隔离吗?
DIO
23 小时 5 分钟前
@kapaseker 是的,希望能实现函数内部嵌套子函数,但是子函数体{...}后置,母函数代码在最前面且能调用后面的子函数。
tbc3211
23 小时 2 分钟前
内联函数 jvm 负责搞定了吧,开发 java 应该不用在意这些
assiadamo
23 小时 1 分钟前
你可以嵌个 nashron js 引擎,java 调用 js 代码。
不过 nashron 支持的 js 语法有限,比如=>就不支持
Nitsuya
23 小时 0 分钟前
lambda 对象, 类型转为 Function 这类的.. 相比 kt 这样做 会导致多这个匿名对象出来...
DIO
22 小时 59 分钟前
@wolfie 因为有些逻辑确实只是为了让函数可读性更好而剥离出来的函数,基本没有类内其他函数复用的可能,后续改起来如果可以 metod 级别隔离,心理负担更小。
meilicat
22 小时 58 分钟前
lambda + function 可以,但还不如写方法。。。java 这块做得确实不如 py 、go 、cpp 好。
wanniwa
22 小时 58 分钟前
不行。没理解为什么有这种需求。
wolfie
22 小时 41 分钟前
@DIO
如果说,其他业务没法复用的话。
你要不针对你的 FooBarService ,定义一个 FooBarHelper
把这些 function 都扔到那里边,写好注释 仅服务于 @link FooBarService#myFunction
acorngyl
22 小时 32 分钟前
不理解,把 multiply(),放类里和放方法里,就是写法不同,代码量上没区别吧?
doubleData 和 multiply 都放一个类里,声明 private ,一样只能 parentFunction 内使用。现在的写法,也不能限制 parentFunction 内的其它方法调用 multiply 吧。
就算是执行的时候,解释器也是把 parentFunction 和 multiply 当作两个独立的对象处理的,跟是不是嵌套,也没关系。parentFunction 说叫 function ,实际上就是个类,生成对象才加载内存的。
yazinnnn0
22 小时 29 分钟前
啥函数式语言支持这种写法?
edwardzcn98
22 小时 15 分钟前
没太看懂问题,函数式编程里也不能自行推断匿名函数行为
BBCCBB
22 小时 7 分钟前
我还以为你是想要用闭包直接在嵌套的函数里用 parent method 里定义的一些参数, 而不需要再次在方法上声明..

结果你就是定义了一个简单方法.
edwardzcn98
22 小时 4 分钟前
@wolfie #15 我觉得这个方案合理,为了可读性半解耦子函数还不如定义一个 helper 写明白,易于维护。

怀疑楼主说的把“λ ...... {...} 函数体”后置是单子组合的写法,但这和你需求的 application 先于 define 不一致啊。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1097182

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX