ClojureScript中用:as保留解构原项,其他语言是否有类似操作?
类似ClojureScript
:as的解构保留原始项功能,其他编程语言是否支持? 在ClojureScript中,我们可以通过:as运算符在解构提取目标元素的同时,将原始待解构的项存储到单独变量中。比如下面这个匿名函数的例子,解构出:a和:b的同时,把整个原始映射存在m里:
((fn [{:keys [a b] :as m}] (println "a is" a) (println "b is" b) (println "m is" m)) {:a "A" :b "B" :c 3 :d 4}) ;; => a is A ;; b is B ;; m is {:a "A" :b "B" :c 3 :d 4} ;; nil
请问是否有其他编程语言支持类似的操作,既能解构提取目标元素,又能保留原始的待解构项?
回答
当然有不少编程语言都支持这类实用的操作,下面我给你列举几个常见的例子,每个都附上代码演示:
JavaScript/TypeScript
JS和TS里实现这个需求非常直观——因为解构本身只是提取对象的属性,原始对象的引用完全可以单独保留,不需要特殊语法:
const obj = { a: "A", b: "B", c: 3, d: 4 }; const { a, b } = obj; console.log("a is", a); console.log("b is", b); console.log("obj is", obj); // 输出: // a is A // b is B // obj is { a: 'A', b: 'B', c: 3, d: 4 }
如果是在函数参数里想直接模拟ClojureScript的写法,你可以把原始对象作为参数传入,再在函数内部解构:
const processObj = (obj) => { const { a, b } = obj; console.log("a is", a); console.log("b is", b); console.log("obj is", obj); }; processObj({ a: "A", b: "B", c: 3, d: 4 });
Python
Python的字典操作和解包同样能轻松实现这个需求。你可以直接保留原始字典的引用,同时提取目标键:
def process_obj(obj): a = obj["a"] b = obj["b"] print(f"a is {a}") print(f"b is {b}") print(f"obj is {obj}") my_obj = {"a": "A", "b": "B", "c": 3, "d": 4} process_obj(my_obj)
要是想用Python的关键字参数解包,也可以结合保留原始对象:
def process_obj(a, b, *, obj): print(f"a is {a}") print(f"b is {b}") print(f"obj is {obj}") my_obj = {"a": "A", "b": "B", "c": 3, "d": 4} process_obj(**my_obj, obj=my_obj)
Kotlin
Kotlin的解构声明设计得非常灵活,你可以在解构的同时直接保留原始对象的引用,不管是局部变量还是函数参数场景都适用:
data class MyData(val a: String, val b: String, val c: Int, val d: Int) fun main() { val myObj = MyData("A", "B", 3, 4) val (a, b) = myObj println("a is $a") println("b is $b") println("myObj is $myObj") // 输出: // a is A // b is B // myObj is MyData(a=A, b=B, c=3, d=4) }
函数参数里的写法也很简洁:
fun processObj(obj: MyData) { val (a, b) = obj println("a is $a") println("b is $b") println("obj is $obj") } processObj(MyData("A", "B", 3, 4))
Scala
Scala的模式匹配和解构同样支持这类操作,比如对case class的解构,同时保留原始实例:
case class MyData(a: String, b: String, c: Int, d: Int) def processObj(obj: MyData): Unit = { val MyData(a, b, _, _) = obj println(s"a is $a") println(s"b is $b") println(s"obj is $obj") } val myObj = MyData("A", "B", 3, 4) processObj(myObj)
你也可以在函数参数里直接结合模式匹配来实现:
def processObj(obj: MyData) = obj match { case MyData(a, b, _, _) => println(s"a is $a") println(s"b is $b") println(s"obj is $obj") } processObj(MyData("A", "B", 3, 4))
内容的提问来源于stack exchange,提问作者user2609980
相关产品推荐
相关产品推荐

