Swift 到 JavaScript 转译器 - 可能吗?
Swift to JavaScript transpiler - possible?
作为 Swift 中的 iOS 开发人员编码,我发现越来越烦人的是必须协调 Swift 中编写的相同代码与 [=38] 中编写的前端开发人员=].在一个地方实现通用功能然后转换为 JS 会更整洁,对吧?
我开始怀疑 Swift 到 JS 编译器是否可行?可能不分享完整的代码,但至少分享一些通用的常用功能。
我在网上找到了这个转译器:SwiftJS。可悲的是,这个并没有真正削减它。
以下代码:
let a = [1, 2]
print(a.count)
returns Invalid Swift code
在演示中。这不会灌输信心。不要介意更复杂的位,如可选或函数重载。
我想知道是否开始一个转译器项目,但后来我意识到有很多陷阱。例如这段代码:
var a = [1, 2]
var b = a
b.append(3)
应该使 a
等于 [1, 2]
并且 b
等于 [1, 2, 3]
。在 JavaScript 中,两者都是 [1, 2, 3]
,因为它们是通过引用而不是值传递的。
是否有可能编写一个合适的转译器?
任何两种图灵完备语言之间的转译器总是可能。这并不意味着它简单、实用或值得。
至少,你可以保证 Swift 到 JS 的转译是可能的,因为你可以将 Swift 编译成 x64 机器代码,并使用 JS disassembler/decompiler 来产生JS。但是,生成的代码将是真正的狗屎JS。
要进行良好的转换,您需要考虑一种语言的所有复杂最佳实践,以及它们在另一种语言中的等效项。这是一项艰巨的任务,对于您想要转译的任何两对语言,必须完成两次(每个方向一次)。转译器如此不常见,而且通常都是废话,这是有原因的。
人们不得不怀疑编写一个 Swift 到 JavaScript 转译器是否有意义,因为这些语言不映射 1:1。除了您提到的那些之外,还有很多陷阱(例如 inout 参数或函数重载)。已经有一些可行的替代方案,例如使用 Haxe/Kotlin 转译为 JavaScript 和 Swift,或者在 Xamarin/React Native 中开发 cross-platform 应用程序。
话虽这么说,两种语言都有许多共同的最佳实践,并且有相当多的功能重叠(例如 closures/assigning 函数到变量)。我不认为有任何功能是无法转译的,尽管一些生成的代码可能非常混乱。
与使用例如Kotlin——您可以获取现有的 Swift 项目并将其转换为 JS,而无需事先决定使用 Kotlin 编写。而且它是您需要学习的一种语言。
我自己开始了一个 transpiler project with live preview 我认为这是对 ShiftJS 的改进。它确实会处理您提到的情况(包括按值传递 arrays/dictionaries)。
尽管如此,它仍在进行中,因为我什至还没有时间实现对 类 的支持。 inout
参数是困扰我的事情之一,尽管可能有一个(丑陋的)解决方案。
var a = 2
func incr(_ a: inout Int) {
a += 1
}
incr(&a)//a now equals 3
可以转译为
var a = 2
function incr(a) {
a.set(a.get() + 1)
}
incr({get: a => a, set: val => a = val})//a now equals 3!
如何破解!
是否可以写一个1:1 Swift到JS转译器?我倾向于是,但还没有定论——我很可能最终 运行 加入一个无法在 JS 中复制的特性。
Swift 被编译为 LLVM。
LLVM可以转换为Javascript:
https://github.com/emscripten-core/emscripten
可以设计一个通过 WebAssembly 将 Swift 翻译成 JavaScript 的编译器,因为已经有两个编译器可以用于此目的:
作为 Swift 中的 iOS 开发人员编码,我发现越来越烦人的是必须协调 Swift 中编写的相同代码与 [=38] 中编写的前端开发人员=].在一个地方实现通用功能然后转换为 JS 会更整洁,对吧?
我开始怀疑 Swift 到 JS 编译器是否可行?可能不分享完整的代码,但至少分享一些通用的常用功能。
我在网上找到了这个转译器:SwiftJS。可悲的是,这个并没有真正削减它。
以下代码:
let a = [1, 2]
print(a.count)
returns Invalid Swift code
在演示中。这不会灌输信心。不要介意更复杂的位,如可选或函数重载。
我想知道是否开始一个转译器项目,但后来我意识到有很多陷阱。例如这段代码:
var a = [1, 2]
var b = a
b.append(3)
应该使 a
等于 [1, 2]
并且 b
等于 [1, 2, 3]
。在 JavaScript 中,两者都是 [1, 2, 3]
,因为它们是通过引用而不是值传递的。
是否有可能编写一个合适的转译器?
任何两种图灵完备语言之间的转译器总是可能。这并不意味着它简单、实用或值得。
至少,你可以保证 Swift 到 JS 的转译是可能的,因为你可以将 Swift 编译成 x64 机器代码,并使用 JS disassembler/decompiler 来产生JS。但是,生成的代码将是真正的狗屎JS。
要进行良好的转换,您需要考虑一种语言的所有复杂最佳实践,以及它们在另一种语言中的等效项。这是一项艰巨的任务,对于您想要转译的任何两对语言,必须完成两次(每个方向一次)。转译器如此不常见,而且通常都是废话,这是有原因的。
人们不得不怀疑编写一个 Swift 到 JavaScript 转译器是否有意义,因为这些语言不映射 1:1。除了您提到的那些之外,还有很多陷阱(例如 inout 参数或函数重载)。已经有一些可行的替代方案,例如使用 Haxe/Kotlin 转译为 JavaScript 和 Swift,或者在 Xamarin/React Native 中开发 cross-platform 应用程序。
话虽这么说,两种语言都有许多共同的最佳实践,并且有相当多的功能重叠(例如 closures/assigning 函数到变量)。我不认为有任何功能是无法转译的,尽管一些生成的代码可能非常混乱。
与使用例如Kotlin——您可以获取现有的 Swift 项目并将其转换为 JS,而无需事先决定使用 Kotlin 编写。而且它是您需要学习的一种语言。
我自己开始了一个 transpiler project with live preview 我认为这是对 ShiftJS 的改进。它确实会处理您提到的情况(包括按值传递 arrays/dictionaries)。
尽管如此,它仍在进行中,因为我什至还没有时间实现对 类 的支持。 inout
参数是困扰我的事情之一,尽管可能有一个(丑陋的)解决方案。
var a = 2
func incr(_ a: inout Int) {
a += 1
}
incr(&a)//a now equals 3
可以转译为
var a = 2
function incr(a) {
a.set(a.get() + 1)
}
incr({get: a => a, set: val => a = val})//a now equals 3!
如何破解!
是否可以写一个1:1 Swift到JS转译器?我倾向于是,但还没有定论——我很可能最终 运行 加入一个无法在 JS 中复制的特性。
Swift 被编译为 LLVM。 LLVM可以转换为Javascript: https://github.com/emscripten-core/emscripten
可以设计一个通过 WebAssembly 将 Swift 翻译成 JavaScript 的编译器,因为已经有两个编译器可以用于此目的: