Ocaml 在脚本中定义闭包变量
我正在尝试将下面的ES6脚本转换为bucklescript,但我一辈子都不知道如何在bucklescript中创建“闭包”Ocaml 在脚本中定义闭包变量,ocaml,interop,ffi,bucklescript,Ocaml,Interop,Ffi,Bucklescript,我正在尝试将下面的ES6脚本转换为bucklescript,但我一辈子都不知道如何在bucklescript中创建“闭包” 从“phoenix”导入{Socket,Presence} 让套接字=新套接字(“/socket”{ 参数:{user_id:window.location.search.split(“=”[1]} }) let channel=socket.channel(“房间:大厅”{}) 让状态=新状态(通道) 功能renderOnlineUsers(状态){ let respon
从“phoenix”导入{Socket,Presence}
让套接字=新套接字(“/socket”{
参数:{user_id:window.location.search.split(“=”[1]}
})
let channel=socket.channel(“房间:大厅”{})
让状态=新状态(通道)
功能renderOnlineUsers(状态){
let response=“”
presence.list((id,{metas:[first,…rest]})=>{
让计数=rest.length+1
响应+=`
${id}(计数:${count})`
})
document.querySelector(“main[role=main]”)。innerHTML=response
}
socket.connect()
presence.onSync(()=>renderOnlineUsers(presence))
channel.join()
我无法明确指出的部分是let response=“”
(在本例中是var,因为bucklescript总是使用var
s):
函数renderOnlineUsers(状态){
let response=“”
presence.list((id,{metas:[first,…rest]})=>{
让计数=rest.length+1
响应+=`
${id}(计数:${count})`
})
document.querySelector(“main[role=main]”)。innerHTML=response
}
到目前为止,我得到的最接近的结果不包括结果
声明
。。。
...
让我们来同步ev=
让result=”“输入
让listFunc=[%raw begin
{|
(id,{metas:[first,…rest]})=>{
让计数=rest.length+1
结果+=`${id}(计数:${count})\n`
}
|}
结束
]在
让我们=
在场。中的listPresence(listFunc)
[%raw{| console.log(result)|}]
...
...
汇编至:
显示同步功能(ev){
var listFunc=(
(id,{metas:[first,…rest]})=>{
让计数=rest.length+1
结果+=`${id}(计数:${count})\n`
}
);
状态列表(listFunc);
返回(console.log(result));
}
结果作为优化被删除,因为它被认为是未使用的。使用依赖于BuckleScript生成的代码的raw
代码通常不是一个好主意,因为在生成的代码中可能会遇到很多意外情况
对编译器认为不可变的变量进行变异也不是一个好主意,因为它将基于值永远不会改变的假设执行优化
这里最简单的修复方法是将[%raw{{console.log(result)}]
替换为Js.log result
,但看看如何在OCaml中编写listFunc
可能会有所启发:
let onpresence同步ev=
让result=ref“”输入
让listFunc=fun[@bs]id项->
让count=Js.Array.length项##元插入
结果:={j|$id(count:$count)\n|j}
在里面
让uu=presence |。(listPresence listFunc)位于
Js.log!结果
请注意,result
现在是一个ref
单元格,这就是在OCaml中指定可变变量的方式ref
单元格使用更新:=
并使用检索其包含的值代码>。另请注意[@bs]
注释,该注释用于指定传递给外部高阶函数的函数所需的参数。使用的字符串插值语法:{j|…|j}
太棒了!是的,我知道要避免生食,这正是我发布的原因。我对OCaml和Bucklescript还是新手。我不知道ref
,谢谢!作为一个附带问题,分解数组或对象的等效方法是什么?(示例js:{metas:[first,…rest]}=obj
实际上没有等价物,因为OCaml中的模式是静态的,不会创建新的值。它们只是绑定到现有值的一部分。因此,您可以使用类似于[|a,b |]的模式。)
它匹配两个元素的数组,但不能有一个需要将旧数组的元素复制到新数组中的数组。你也不能分解对象,因为它们也是动态的。你通常使用的是记录和列表,它们的工作方式与你在这里期望的完全相同。不幸的是,这对JavaScript互操作没有帮助因为JavaScript没有记录和列表,所以它有对象和数组。不幸的是,你只能用老式的方式来做。