我知道可以通过 Runnable 来让 lambda 前置并在后面调用,而且最终实际上是通过包装成私有函数运行,不会有额外开销。但是有没有办法让子函数体后置,业务代码在前?
函数式编程貌似可以做到。Java 中有没有办法呢。
至于为什么不用 kt ,嗯,公司业务积重难返了。
function parentFunction() { // 业务代码部分 const data = [1, 2, 3, 4, 5]; const doubled = doubleData(daa); 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 } }
1 iPisces77 304 天前 不支持,java 所有方法要么放在类里,要么放在接口里 |
![]() | 2 cpstar 304 天前 可以匿名类+继承/实现的方法 |
![]() | 3 kapaseker 304 天前 没有特别明白你说的啥,但是 Java 我记得也支持 lambda 表达式以及 this::someMethod 这种写法啊。还是说你就是希望像 Kotlin 那样,编写 aabb {} 代码? |
![]() | 4 lisongeee 304 天前 你的 js 能运行是因为 function 有变量提升,你换成 const 就不行了而且会报错 此外如果你在函数里访问了外部 const 变量但是此时 const 变量还未初始化,也会报错 |
![]() | 5 qW7bo2FbzbC0 304 天前 @kapaseker lamda 我记得也是生成匿名类把这个方法附加上去?楼主说的这种,纯 OOP 风格的语言应该有点难度 |
6 justdoit123 304 天前 个人实在不喜欢函数里声明大量函数的做法。 感觉一打开一个函数,就要先面对大量的“子函数”实现细节,然后才能看到函数本身的逻辑,这个跟你提问的苦恼一样。我感觉组织这种逻辑,还是class 最适合。 |
![]() | 7 wolfie 304 天前 Why ??? 同一个 class 下 定义 private method 不行吗? 必须 method 级别隔离吗? |
9 tbc3211 304 天前 内联函数 jvm 负责搞定了吧,开发 java 应该不用在意这些 |
10 assiadamo 304 天前 via iPhone 你可以嵌个 nashron js 引擎,java 调用 js 代码。 不过 nashron 支持的 js 语法有限,比如=>就不支持 |
11 Nitsuya 304 天前 lambda 对象, 类型转为 Function 这类的.. 相比 kt 这样做 会导致多这个匿名对象出来... |
![]() | 13 meilicat 304 天前 lambda + function 可以,但还不如写方法。。。java 这块做得确实不如 py 、go 、cpp 好。 |
![]() | 14 wanniwa 304 天前 不行。没理解为什么有这种需求。 |
![]() | 15 wolfie 304 天前 ![]() |
16 acorngyl 304 天前 不理解,把 multiply(),放类里和放方法里,就是写法不同,代码量上没区别吧? doubleData 和 multiply 都放一个类里,声明 private ,一样只能 parentFunction 内使用。现在的写法,也不能限制 parentFunction 内的其它方法调用 multiply 吧。 就算是执行的时候,解释器也是把 parentFunction 和 multiply 当作两个独立的对象处理的,跟是不是嵌套,也没关系。parentFunction 说叫 function ,实际上就是个类,生成对象才加载内存的。 |
17 yazinnnn0 304 天前 啥函数式语言支持这种写法? |
![]() | 18 edwardzcn98 304 天前 没太看懂问题,函数式编程里也不能自行推断匿名函数行为 |
![]() | 19 BBCCBB 304 天前 我还以为你是想要用闭包直接在嵌套的函数里用 parent method 里定义的一些参数, 而不需要再次在方法上声明.. 结果你就是定义了一个简单方法. |
![]() | 20 edwardzcn98 304 天前 @wolfie #15 我觉得这个方案合理,为了可读性半解耦子函数还不如定义一个 helper 写明白,易于维护。 怀疑楼主说的把“λ ...... {...} 函数体”后置是单子组合的写法,但这和你需求的 application 先于 define 不一致啊。 |
![]() | 21 Hilalum 304 天前 |
22 caiqichang 304 天前 你这段 kotlin 代码可以运行? |
![]() | 23 xuanbg 304 天前 lambda 可以把方法作为参数。但是,普通的方法调用你把对象作为参数就行了,没必要非得把对象的方案作为参数啊 |
![]() | 24 xuanbg 304 天前 对象的方法,不是方案。笔误 |
![]() | 25 Belmode 304 天前 Java 做不到。一种语言有一种语言的范式,别套。 |
26 layxy 304 天前 lambda 可以在函数内定义函数,但是必须在调用前定义 |
![]() | 27 ychost 304 天前 我们也是在历史业务里面嵌入 kotlin 的,慢慢迭代呗不存在积重难返,kt 和 java 交互没啥卡点,甚至还可以把 Groovy 加进来作为扩展点 |
28 Dropless 304 天前 ![]() 题外话, C# 的函数支持这样, 就跟 js 里一样, 一般叫 local function. 一个函数里有大量的 local function 肯定是不推荐的, 不过 js 里因为有闭包的需求, 这种范式倒是不少见. 如果一个函数(A)太长, 那么可以把部分代码单独作为另外一个函数(B), 如果 B 只会被 A 调用, 那么把 B 作为 A 的 local function 是合理的, 这样可以减轻对类成员的"污染" |
![]() | 29 xiangyuecn 304 天前 我的 java 骚操作,可以让 java 函数返回多个结果,用在闭包里面也是一样的,原理就是 1 个元素的数组 final Func[] xxx=new Func[]{ null } .... 你的 lambda{ xxx[0].xxx() } xxx[0]=()->{} 你的函数定义放后面 |
30 Cbdy 304 天前 Java 不是可以定义 Lambda 吗? |
![]() | 31 netabare 303 天前 via Android 没有办法做到,某种程度上说这是 Java 的一大缺陷了。 放心,以后也不会修,因为这个功能养活了许多设计模式。 |