国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS or C#?不存在的腳本之爭

YFan / 1754人閱讀

摘要:既然小匹夫說不是,但的確有好幾種腳本語言啊,那和相比,我們應該如何抉擇呢所以最后小匹夫會分析一下。因為最后小匹夫意識到了和是兩種差別很大的語言。

前言

又來到了周末,小匹夫也終于有了喘口氣寫寫博客的時間和精力。話說周五的下午,小匹夫偶然間晃了一眼游戲蠻牛Unity3D的QQ群,又看到了一個Unity3D開發中老生長談的問題,“我的開發語言究竟是選擇JavaScript呢?還是C#呢?”。對這個問題,小匹夫也覺得的確該認真的梳理一下了。那么為何說JavaScript和C#的爭論根本就不存在呢?首先,我們要知道Unity3D中的Js腳本究竟是什么?最準確的學名,我想應該叫做UnityScript (因為Unity-Technologies在github上托管的代碼就叫這個名字。。。)。那為何UnityScript不是JavaScript呢?我們就繼續分析一下UnityScript vs JavaScript好了。既然小匹夫說UnityScript不是JavaScript,但Unity3D的確有好幾種腳本語言啊(C#,UnityScript, Boo),那和C#相比,我們應該如何抉擇呢?所以最后小匹夫會分析一下C# vs UnityScript。

最熟悉的陌生人 - UnityScript

小匹夫的上一篇文章《Mono為何能跨平臺?聊聊CIL(MSIL)》中介紹了一下Unity3D跨平臺的基礎。那就是借助了CIL,首先將源代碼(例如C#)編譯成CIL(其實是CIL assembly),之后再通過JIT或者是FULL-AOT將CIL編譯成目標平臺的原生代碼,進而實現了一套代碼,多個平臺使用的跨平臺功能。所以可以想見,作為Unity3D中的“JS"(之后我將使用UnityScript來稱呼)同樣也會先被編譯成CIL代碼,之后再編譯成對應平臺的原生代碼。換言之,Unity3D實現了一套在.NET平臺上和C#處于”相同層面“的語言UnityScript。開發了一套自己的語言,這聽上去簡直太瘋狂了是嗎?其實一點也不。剛才說了,源代碼都要先編譯成CIL,所以只要能有一套編譯器能夠把UnityScript的語法分析識別并編譯成CIL,那問題不就解決了嗎?當然,如果有現成的,能符合以下三條的語言作為參考,那UnityScirpt的開發者應該是感激不盡了吧。哪三點呢?

是.Net層面的語言。

像腳本語言

有編譯器能把它編譯成CIL

沒錯,聰明的看官你一定想到了,那位一直隱藏的很深的幕后人物,Unity3D腳本三巨頭之一的Boo了吧。都說Boo是Unity3D得腳本語言之一,可是為啥就沒見有什么人用過呢?原因之一可能就是Unity3D最初之所以要引入Boo,純粹是為了UnityScript服務的。Boo作為一個.NET平臺的第三方語言,寫起來也很像腳本語言,并且有對應的編譯器能夠實現從Boo到CIL的過程。Boo寫起來是像這個樣子的:(更多關于Boo的內容請參見概覽CLI之上的新語言——Boo)

import System
import System.Net
import System.Threading
url, local = argv
client = WebClient()
call = client.DownloadFile.BeginInvoke(url, local)
while not call.IsCompleted:
        Console.Write(".")
        Thread.Sleep(50ms)
Console.WriteLine()

簡而言之,UnityScript是脫胎于Boo的。雖然看上去UnityScirpt和Boo長的不像,但要明白語法不是問題,語義才是。只要能把UnityScript的語法解析成Boo的編譯器能認識的,那么UnityScript的編譯器的大部分工作就可以交給Boo的編譯器來實現了。所以,基于現成的Boo語言,開發UnityScript編譯器的工作就只剩下語法解析而已了,事實上他們也的確是這樣做的。

而當我們來到UnityScript在github的托管頁面,發現竟然是Boo的開發者在維護,而UnityScript的編譯處理邏輯所在的文件是一個boo文件--UnityScriptCompiler.boo。

雖然不懂boo語言,但是還是可以看到會引入boo的編譯器:

import Boo.Lang.Compiler

也會有針對UnityScript的語法進行解析以供Boo的編譯器識別的過程:

pipeline.Insert(0,
UnityScript.Steps.PreProcess())
pipeline.Replace(Boo.Lang.Compiler.Steps.Parsing,
UnityScript.Steps.Parse())
pipeline.Replace(Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces,
UnityScript.Steps.IntroduceUnityGlobalNamespaces())
pipeline.InsertAfter(Boo.Lang.Compiler.Steps.PreErrorChecking,
UnityScript.Steps.ApplySemantics())
pipeline.InsertAfter(UnityScript.Steps.ApplySemantics,
UnityScript.Steps.ApplyDefaultVisibility())
pipeline.InsertBefore(Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions,
UnityScript.Steps.ProcessAssignmentToDuckMembers())
pipeline.Replace(Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping,
UnityScript.Steps.ProcessUnityScriptMethods())

好吧,我才不會告訴你在同一個github頁面關于UnityScript的介紹是:

A JavaScript implementation based on the Boo programming language.

那么UnityScript的編譯器到底放在哪里呢?(從UnityScript到CIL)請看下圖:

Mac版的路徑:/Applications/Unity/Unity.app/Contents/Frameworks/Mono/lib/mono/unity/us.exe

Win版的路徑:U3D路徑/Editor/Data/Mono/lib/mono/unity/us.exe

說了這么多,還是需要為我們這篇文章的主角UnityScript正個名:是靜態語言且需要編譯,脫胎于Boo語言,和JavaScript除了后綴之外沒有關系。所以與其糾結“U3D的javascript到底和javascript有多形似”,倒不如考慮下UnityScript和Boo有多么神似。

UnityScript vs JavaScript

很多提出小匹夫在前言中提到的那個老生常談問題的盆油,往往認為UnityScript和我們平時所說的JavaScript是一樣的,即使有人意識到有所區別,但是認為本質上也還是和JavaScript屬于同一范疇。期初小匹夫也是這樣認為的,因為曾經使用過cocos2d-js開發游戲的緣故,所以當聽說Unity3D他喵的竟然支持JS腳本,那叫一個開心啊。可是最初的開心往往也暗示著最后的失望。

因為最后小匹夫意識到了UnityScript和JavaScript是兩種差別很大的語言。

其實所謂的JavaScript是一個很泛泛的名字,可以用來指任何實現了ECMAScript標準的語言(求JS大神輕噴。。。),而UnityScript主觀上根本就沒有試圖去實現甚至是接近該標準。所以很多JavaScript的庫如果只是單純的拷貝粘貼,在Unity3D中并不會運行的特別”順利“(之所以加引號是因為很多都運行不起來吧)。

那么兩者究竟有多大的差別呢?最主要和本質的區別前文小匹夫已經說過了,它倆除了長相差不多,壓根就沒啥聯系。但是還是需要有個更直觀的認識。那么小匹夫就簡單總結一下,JavaScript和UnityScrip的差別吧。

JavaScript沒有類的概念

JavaScript沒有類的概念。因為它是一種基于原型的語言,繼承發生在對象和對象之間(更靈活,換言之,更動態),而非類和類之間。

舉個例子:

function Person() {
   this.name = ["chenjiadong"];
}
 
var c = new Person();
console.log(typeof c.introduce);
 
Person.prototype.introduce = function() {
   console.log("I am  "+this.name+".");
};
 
console.log(typeof c.introduce);
c.introduce();

如你所見,在匹夫有限的js知識中,同樣存在著對象和原型的概念。通過關鍵字new,我們可以用方法Person創建出一個對象c,此時的小c還是很單純的,不會introduce自己。但是如果Person經過進化,學會了介紹自己introduce,那么之前創建的小c也同樣學會了介紹自己introduce。

但是在UnityScript中可不能這樣,因為它有類的概念。你一旦定義了你的類,那么在程序運行時這個類也就不能改動了。

文件名的講究

不知道各位盆油有木有發現,一個新建的UnityScript文件中好像并沒有聲明一個類。相反,看上去很像一般的javascript的寫法。比如這樣Test.js:

#pragma strict

function Start () {

}

function Update () {

}

其實原因就在于文件名了。U3D中大多數.js文件都代表一個類,所以自然而然的,文件的名字就被用來稱呼這個類了。(當然說大多數文件都是這樣的含義就是,你也可以在一個文件中定義多個類,比如不繼承自MonoBehav的類)。

所以上面的代碼就等效于這樣的C#代碼:

using UnityEngine;

public class Test : MonoBehaviour {
    void Start () {

    }    
    // Update is called once per frame
    void Update () {
        
    }
}

反觀JavaScript,則僅僅是執行文件中的代碼,而和文件名無關。

除了這兩條比較“宏觀”的差別之外,語法上是否還有什么不同呢?有啊~看官,您繼續瞧好兒咯~

語法差異之一次能聲明幾個變量

在javascript中,經常可以這么干:

var x = 1, y = 2;

但在UnityScript中這樣寫,U3D通常會這么說

語法差異之分號的必要性

以前記得在微博上看到過一個大學教授吐槽過一個javascript的“bug”,如圖:(小匹夫竟然憑借記憶力找到那條去年的微博...求贊)

所以,讓大V掉坑里的,javascript的特性之一,就是程序在執行時會默認在行尾加“;”,換句話說,作為人類或者猿類的我們可以不在行尾寫分號。

而UnityScript為了避免這種很可能造成bug的寫法,對分號做出了要求。接下來不用我多說了吧。

反正你不寫分號,U3D大概會這么說:

語法差異之“賦值表達式”能否作為表達式賦值?

實話實說,小匹夫也不知道怎么想的這么一繞口的小標題。但是小匹夫記得在javascript中可以這么寫:

var x = 3; // x is 3
var y = (x=x+2); // x is 5, y is 5

所以這里,x=x+2 這個賦值表達式作為一個表達式給y賦值。

但是在UnityScript中同樣是不支持這種寫法的。這次U3D會和你嘰歪很多話。

語法差異之var和類型那點事

聊javascript終究繞不過去的一個話題,那就是聲明變量時的var。假設你聲明變量時,不帶var,則該變量會默認成為全局變量。但是聲明變量不帶個var,在UnityScript中可行不通。

好吧,那妥協之,在UnityScript中我帶var還不行嘛?那是不是就可以像JavaScript一樣,在類型上無拘無束任我飛了?

比如下面的代碼,我在javascript上和unityscript上都運行的很完美啊。

 //UnityScript 和 JavaScript都能運行哎~
var x;
x = 3;
x = new Array();

這樣看起來,貌似UnityScript是動態語言啊!簡直是視類型如無物啊。好多盆油到這里就迷糊了,接著就產生了那樣的錯覺。

其實作為靜態語言,在編譯器進行編譯時,變量到底是什么類型它可得門清,所以在UnityScript中,上面代碼里的x到底是什么類型可是確定好的。 覺得奇怪是嗎?那我們把等效的代碼寫一下各位看官就明白了。

//在unityscript中等效于下面
Object x;
x = 3;
x = new Array();

對,原來x是Object類型。所有的類型都派生自它,換言之,所有的類型都能轉化成它。所以3能轉化為Object,Array也能轉化成Object。這也就是UnityScript看起來是動態類型的原因。(頻繁裝箱,肯定會影響效率)
所以你如果調用一個Object沒有的方法,可能會有這樣的提示:

當然,關于var的話題還有很多,比如C#也有,但是和這里并非完全相同。同樣,javascript和unityscript可以聊的話題也還有很多,但是受限于篇幅,這里點到即止。

C# vs UnityScript

終于來到咱們經常爭論的火藥桶話題了,到底C#和Unity3D里的JS誰好呢?

最常見的問題無非是:_用js寫的u3d游戲和用c#寫的u3d游戲,到底誰的運行效率高啊?_

最常見的回答為非是:_肯定是C#啊,因為js是動態的。肯定不如編譯的語言好。_

第二常見的問題無非是:_用js開發和用c#開發,哪個更快更適合我啊?_

第二常見的回答無非是:_js適合個人開發,敏捷快速。c#適合公司開發,規范嚴謹。_

咱們還是用和剛才討論與javascript的區別時一樣的思路來整理C#和UnityScript的不同,也就是按照先本質,再表現的順序。同時兼顧回答一下上面的兩個問題。

本質求同存異

開篇就說了,UnityScript是和C#同一個層面的語言,也需要經歷從源代碼到CIL中間語言過渡,最終到編譯成原生語言的過程。所以本質上,最終運行的都是從CIL編譯而來的原生機器語言。但的確會有C#比較快的現象,那么問題出在哪呢?

一個可能但不是唯一的答案就是UnityScript和C#生成CIL中間語言不同。

這一點想想也很簡單,就像上文提到的var的問題,如果使用Object來處理var的問題,則不可避免的是頻繁的裝箱拆箱的操作,這對效率的影響是很大的。

所以的確,C#的速度更快,但原因是UnityScript會涉及到頻繁的裝箱拆箱操作,進而生成的CIL代碼與C#有差異,而并非UnityScript是動態語言且沒有經過編譯。

現實很單純

開發到底是使用C#還是UnityScript呢?如果不考慮運行的效率,僅僅考慮開發時候的感受,小匹夫就談談自己的看法好啦——那就是珍惜時間,遠離UnityScript。

首先有幾個事實我們要清楚:

UnityScript是脫胎于.NET平臺的第三方語言Boo的。所謂的第三方語言和C#的區別,就跟自己到底是不是親生的,爹到底是不是隔壁老王是一樣的。差距可能是全方位,立體式的。社區支持,代碼維護,甚至是編譯出來的CIL代碼質量都可能有很大的差距。選擇UnityScript之前,問問自己之前聽說過Boo嗎?別忘了UnityScript和Boo的淵源。

UnityScript和JavaScript除了長得像之外,根本就沒有什么關系。你在JavaScript里如魚得水,在UnityScript中如果不小心就可能埋下隱患,而一些隱患可能藏得很深。而且UnityScript也是靜態語言,也需要編譯,所以看不出來選擇它作為開發語言為什么會有人覺得快。

插件的支持。貌似大多數都是C#寫的吧。

好吧,如果上面的3點都不能說動你,那就看看官方的態度好了。

U3D官方團隊基于數據分析做出的一個語言被使用的百分比圖。

由于Boo語言的使用量基本可以忽略,所以從Unity5.0版本開始就會停止對Boo的文檔支持。同時消失的還有從菜單創建Boo腳本的選項“Create Boo Script”。從U3D團隊對Boo的態度,也可以窺見和Boo聯系密切的UnityScript未來的走勢。

同時U3D團隊也會把支持的重心轉移到C#,也就是說文檔和示例以及社區支持的重心都在C#,C#的文檔會是最完善的,C#的代碼實例會是最詳細的,社區內用C#討論的人數會是最多的。

所以到底如何選擇,各位盆友也都應該有了自己的認識咯。

天色已晚,匹夫睡覺去也~

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78343.html

相關文章

  • SegmentFault 技術周刊 Vol.40 - 2018,來學習一門新編程語言吧!

    摘要:入門,第一個這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數式編程語言,它的代碼運行在之上。它通過編輯類工具,帶來了先進的編輯體驗,增強了語言服務。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經到來了,總結過去的 2017,相信小伙們一定有很多收獲...

    caspar 評論0 收藏0
  • SegmentFault 技術周刊 Vol.40 - 2018,來學習一門新編程語言吧!

    摘要:入門,第一個這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數式編程語言,它的代碼運行在之上。它通過編輯類工具,帶來了先進的編輯體驗,增強了語言服務。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經到來了,總結過去的 2017,相信小伙們一定有很多收獲...

    nihao 評論0 收藏0
  • SegmentFault 技術周刊 Vol.40 - 2018,來學習一門新編程語言吧!

    摘要:入門,第一個這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數式編程語言,它的代碼運行在之上。它通過編輯類工具,帶來了先進的編輯體驗,增強了語言服務。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經到來了,總結過去的 2017,相信小伙們一定有很多收獲...

    Drummor 評論0 收藏0
  • [原]深入對比數據科學工具箱:Python和R之爭[2016版]

    摘要:概述在真實的數據科學世界里,我們會有兩個極端,一個是業務,一個是工程。偏向業務的數據科學被稱為數據分析,也就是型數據科學。所以說,同時學會和這兩把刷子才是數據科學的王道。 showImg(https://segmentfault.com/img/bVAgki?w=980&h=596); 概述 在真實的數據科學世界里,我們會有兩個極端,一個是業務,一個是工程。偏向業務的數據科學被稱為數據...

    whidy 評論0 收藏0
  • 30歲零基礎自學編程,先學哪種語言最好?

    摘要:大學,光學工程研究生畢業,和程序猿完全不搭邊。那怎么辦,試著學一學唄,學習才是程序猿的天性。所以我在想程序猿是不是都需要新知識刺激一下,才能保持興奮的頭腦。有句話說的很對程序猿就像好奇的貓,追著毛球的線頭玩,最后一個毛球在腦袋里攪漿糊。 說說我自己的經歷。211大學,光學工程研究生畢業,和程序猿完全不搭邊。 畢業后進了成都某國字頭研究所,在行業里摸爬滾打了四年,2018年機緣巧合在家養...

    xietao3 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<