Swift 到 JavaScript 转译器 - 可能吗?

Posted

技术标签:

【中文标题】Swift 到 JavaScript 转译器 - 可能吗?【英文标题】:Swift to JavaScript transpiler - possible? 【发布时间】:2017-01-15 18:10:25 【问题描述】:

作为一名使用 Swift 编码的 ios 开发人员,我发现必须将使用 Swift 编写的相同代码与使用 javascript 编码的前端开发人员协调起来越来越烦人。在一个地方实现通用功能,然后翻译成 JS 会更整洁,对吧?

我开始怀疑 Swift to JS 编译器是否可行?也许不分享完整的代码,但至少有一些通用的常用功能。

我在网上找到了这个转译器:SwiftJS。可悲的是,这个并没有真正削减它。

以下代码:

let a = [1, 2]
print(a.count)

在演示中返回 Invalid Swift code。这不会灌输信心。不要介意更复杂的部分,比如可选或函数重载。

我想开始一个转译器项目,但后来我意识到有很多陷阱。例如这段代码:

var a = [1, 2]
var b = a
b.append(3)

应该使a 等于[1, 2]b 等于[1, 2, 3]。在 JavaScript 中,两者都是 [1, 2, 3],因为它们是通过引用而不是值传递的。

是否有可能编写一个合适的转译器?

【问题讨论】:

是的,但你不仅要转换语法,还要转换语义。 Lambdas、数组、字典、对象和几乎所有的语言结构在另一种语言中的行为都不同,因此这是一个非常有野心和复杂的问题需要解决。更不用说这需要很多时间。 我认为有一个相当成熟的 c 到 javascript 转换器,sitepoint.com/…。如果您使用 obj-c 而不是 swift,您可能会从中得到一些用处 【参考方案1】:

任意两种图灵完备语言之间的转译器总是 可能。这并不意味着它简单、实用或值得

至少,您可以保证 Swift 到 JS 的转换是可能的,因为您可以将 Swift 编译为 x64 机器代码,并使用 JS 反汇编器/反编译器来生成 JS。但是,生成的代码将是非常糟糕的 JS。

要进行良好的转换,您需要考虑一种语言的所有错综复杂的最佳实践,以及它们在另一种语言中的对应物。这是一项艰巨的任务,对于您想要转换的任何两对语言,必须执行两次(每个方向一次)。转译器如此不常见而且通常是废话是有原因的。

【讨论】:

【参考方案2】:

人们不得不怀疑编写 Swift 到 JavaScript 转译器是否有意义,因为这些语言不是 1:1 映射的。除了您提到的那些之外,还有许多陷阱(例如 inout 参数或函数重载)。已经有一些可行的替代方案,例如使用 Haxe/Kotlin 转换为 JavaScript 和 Swift,或者在 Xamarin/React Native 中开发跨平台应用程序。

话虽如此,这两种语言都有许多共同的最佳实践,并且具有相当大的功能重叠(例如闭包/将函数分配给变量)。我不认为有任何特性是无法转换的,尽管一些生成的代码可能非常混乱。

与使用例如Kotlin - 您可以获取现有的 Swift 项目并将其转换为 JS,而无需事先决定使用 Kotlin 编写。而且它是您需要学习的一种语言。

我自己创建了一个transpiler project 和live preview,我认为这是对ShiftJS 的改进。它确实会处理您提到的情况(包括按值传递数组/字典)。

不过,它仍在进行中,因为我什至还没有开始实施对类的支持。 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 中复制的功能。

【讨论】:

好吧,现在破解它至少让它工作 - 我们总是可以稍后修复它:) 我最近了解了咖啡脚本。它有一些语言特性,比如可选项,不直接绑定到 javascript,但它们使它工作。我相信 Swift 到 Javascript 的转译器是值得的。 Swift 在 Apple 生态系统之外引起了人们的兴趣,让它在网络上运行将是一大优势。【参考方案3】:

Swift 被编译为 LLVM。 LLVM 可以转换为 Javascript: https://github.com/emscripten-core/emscripten

【讨论】:

很遗憾,将 Swift 编译为 JavaScript using Emscripten 似乎不可行。【参考方案4】:

可以设计一个通过 WebAssembly 将 Swift 转换为 JavaScript 的编译器,因为已经有两个编译器可以用于此目的:

可以使用 SwiftWasm 将 Swift 编译为 WebAssembly,并且 可以使用 wasm2js 将 WebAssembly 编译为 JavaScript。

【讨论】:

以上是关于Swift 到 JavaScript 转译器 - 可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 的 TypeScript 到 JavaScript 转译器

swift 聊天表情emoji转译——从转译文字到聊天列表

swift 聊天表情emoji转译——从转译文字到聊天列表

swift 聊天表情emoji转译——从转译文字到聊天列表

swift 聊天表情emoji转译——从键盘到输入框

swift 聊天表情emoji转译——从键盘到输入框