如何將JavaScript轉化成Swift?(二)
昨天讓同事隨意寫了一段JavaSCript
程式碼:
function showdata() { var array = [0, 1, 2, 3, 4]; var result = true; if (result) { for (let index = 0; index < array.length; index++) { console.log(array[index]); } } else { console.log("noooooo!") } var obj = { name: 'wuli', sex: 0, age: 21 }; var string = "woxinshensihai"; if (result) { console.log(string) } console.log(obj); } 複製程式碼
然後用翻譯程式進行翻譯,結果如下:
func showdata() { var array = [ 0, 1, 2, 3, 4, ] var result: Bool = true if result { for (index, item) in array.enumerated() { print(array[index]) } } else { print("noooooo!") } var obj = NamesexageModel(name: "wuli", sex: 0, age: 21) var string: String = "woxinshensihai" if result { print(string) } print(obj) } 複製程式碼
生成的Model
檔案:
class NamesexageModel: NSObject { var name: String var sex: Int var age: Int } 複製程式碼
從效果來看感覺還可以。。。
For 迴圈翻譯
上篇文章中沒有涉及for 迴圈
的翻譯,這裡補充一下:
JavaScript
的For
寫法和Swift
中的差異比較大,主要是因為Javascript
中的Array
並不像大部分其他語言的陣列。首先,Javascript
中的Array
在記憶體上並不連續,其次,Array
的索引並不是指偏移量。實際上,Array
的索引也不是Number
型別,而是String
型別的。我們可以正確使用如array[0]
的寫法的原因是語言可以自動將Number
型別的0
轉換成String
型別的“0”
C 風格的 for 迴圈
這種寫法應該是JavaScript中用的最多的
for (let index = 0; index < array.length; index++) { console.log(array[index]); } 複製程式碼
但是Swift
自從Swift3.0
開始不再支援C-Type
的寫法,這就有點蛋疼了
在Swift
中的for迴圈
寫法
for (index, item) in array.enumerated() { print(array[index]) } 複製程式碼
對比兩種語言for迴圈的實現,for迴圈方法體內部差不多,但是for迴圈的寫法相差很多,所以我們主要修改let index = 0; index < array.length; index++
這一段程式碼
先看一下for迴圈的AST:
"body": [ { "type": "ForStatement", "init": { "type": "VariableDeclaration", "declarations": [ { "type": "VariableDeclarator", "id": { "type": "Identifier", "name": "index" }, "init": { "type": "Literal", "value": 0, "raw": "0" } } ], "kind": "let" }, "test": { "type": "BinaryExpression", "left": { "type": "Identifier", "name": "index" }, "operator": "<", "right": { "type": "MemberExpression", "object": { "type": "Identifier", "name": "array" }, "property": { "type": "Identifier", "name": "length" }, "computed": false } }, "update": { "type": "UpdateExpression", "operator": "++", "prefix": false, "argument": { "type": "Identifier", "name": "index" } } ... ... 複製程式碼
body
下面的節點是ForStatement
說明執行的是escodegen.js
中的ForStatement
方法,想要從for (let index = 0; index < array.length; index++) {
轉換成for (index, item) in array.enumerated() {
我們只需要獲取到index
關鍵字、array
關鍵字即可
if (stmt.test) { // 獲取 index 關鍵字 result.push(stmt.test.left.name) result.push(', item) in ') // 獲取 array 關鍵字 result.push(stmt.test.right.object.name) result.push('.enumerated()') } 複製程式碼
這樣就可以生成for (index, item) in array.enumerated()
這一段程式碼用來生成index ++)
只需要將它註釋掉或者刪除即可
if (stmt.update) { result.push(space); result.push(that.generateExpression(stmt.update, Precedence.Sequence, E_TTT)); result.push(')'); } else { result.push(')'); } 複製程式碼
ForIn for 迴圈
for (index in array) { console.log(array[index]); } 複製程式碼
ForOf for 迴圈
for (let item of array) { console.log(item); } 複製程式碼
Swift中對應的寫法:
for item in array { print(item) } 複製程式碼
這裡翻譯比較簡單 只需要將 of 改成 in 即可
程式碼格式化
翻譯程式生成的程式碼在格式方面不是很美觀,這裡藉助swiftformat
來對程式碼進行格式化,swiftformat
的安裝很簡單,只需要:
> brew update > brew install swiftformat 複製程式碼
通過 JavaScript 執行swiftformat fileName.swift --swiftversion 4.2
const { exec } = require('child_process'); exec('swiftformat ./Swift_Code/' + fileName + '.swift --swiftversion 4.2 ', (err, stdout, stderr) => { if(err) { return; } }) 複製程式碼
關於如何翻譯JavaScript
的網路請求,由於JavaScript
、Swift
都有各自的網路請求庫,這裡需要統一方法名、引數,每個語言也需要封裝各自的網路請求庫;其次,Swift
的JSON
解析需要一個ClassModel,這裡需要將JSON
轉 Swift Model Class......
未完待續。。。