Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
者|何婧譽
編輯|小智
編程語言的圣戰(zhàn),除了語言種類之分,也有動靜門派之別。我們寫著靜態(tài)語言往往想著動態(tài)語言的靈活,寫著動態(tài)語言又容易想著靜態(tài)語言的穩(wěn)定和可靠。常聽到有人說,Clojure 確實優(yōu)美,但動態(tài)語言實在駕馭不了,怎么辦?
注:本文整理自 Morgan Stanley VP 何婧譽在 QCon 2017 北京站上的演講,原題為:《屬兔的處子——喜歡 Clojure,但怕動態(tài)語言太靈活怎么辦》。
寫在前面
古話說的好,靜若處子,動若脫兔。這個我覺得非常適合形容動靜態(tài)語言的區(qū)別,靜態(tài)語言因為類型系統(tǒng)的關(guān)系,一直給人的是很穩(wěn)定、很可靠,但是可靠到一定程度就變成了死板,會變成一個牢獄或者困住業(yè)務(wù)上所需的靈活性,因此常常需要很多層抽象,很多層膠水代碼,代碼就開始變得非常的晦澀,非常的難懂,而動態(tài)語言則完全是相反的。
常聽到有人說,Clojure 確實優(yōu)美,但動態(tài)語言實在駕馭不了啊!沒有類型的幫助,在涉及到復(fù)雜的數(shù)據(jù)結(jié)構(gòu)之后很容易失去對現(xiàn)有程序的理解,易讀性也會急速下降,而這也確實是 Clojure 作為動態(tài)語言所造成的問題。但是部分解決這個問題的辦法總是有的。core.typed 和 core.spec 兩個核心庫就可以幫助我們緩解動態(tài)語言太過野性框不住的問題,而本次演講的任務(wù)就是向大家介紹這兩個庫,以及這兩個庫解決這一問題的不同角度。
靜態(tài)語言 VS 動態(tài)語言
靜態(tài)語言因為類型系統(tǒng)的關(guān)系,一直給人的是很穩(wěn)定、很可靠,但是可靠到一定程度就變成了死板,會變成一個牢獄或者困住業(yè)務(wù)上所需的靈活性,因此常常需要很多層抽象,很多層膠水代碼,代碼就開始變得非常的晦澀,非常的難懂。動態(tài)語言則完全是相反的,所有東西都是從類型上來講,以函數(shù)為例,靈活性已經(jīng)足夠了,但是通常我們寫著寫著就忘記數(shù)據(jù)長什么樣子了,你可能今天寫了一個函數(shù)說,輸入一個函數(shù)的數(shù)據(jù),然后過了一個星期之后,我已經(jīng)完全忘記這個數(shù)據(jù)是什么東西了,因為生產(chǎn)環(huán)境里面,類型系統(tǒng)在沒有編譯器的幫助下,基本上都是一次性的,這個問題對于用戶來說有相當大的困擾。
一直以來,這兩派之間沒有爭出特別的高低,靜態(tài)語言笑動態(tài)語言做不出大系統(tǒng),動態(tài)語言笑靜態(tài)語言寫的太慢、廢話太多,今天這個主題當然不可能解決這個紛爭,但是希望通過 Clojure 這個語言可以給大家一些不太為人知的思路。馬上就有人來問了,我寫 Clojure 就是為了逃避這樣的內(nèi)容來寫系統(tǒng),這樣靈活多好用啊,我想寫什么就寫什么,快速原型靠的就是這個,我非常同意這一點。
簡單示例
在 Clojure 里面有一個 json,因為動態(tài)語言的關(guān)系相當?shù)暮唵危耆珱]有廢話。這個函數(shù)我覺得哪怕是不寫 Clojure 的,這個也是應(yīng)該很能讀的懂的。首先有一個 Java 的 Reader,是 FileReader,這個 Reader 被傳遞到了這個 json 的函數(shù)里面,讀出來文件內(nèi)容,讀到 Map 里面,但是讀完之后,你知道數(shù)據(jù)長什么樣嗎?不知道,下次換一個 json 文件,同樣的函數(shù)可以同樣讀,但是你不知道讀出來是什么東西。講到這里就已經(jīng)有一點難度在里面了。
現(xiàn)在看一下,我現(xiàn)在讀完了要處理,我處理之后,我寫任意一個函數(shù),如果說你不看這個函數(shù)寫的什么東西,你知道它處理完成之后長什么樣嗎?不知道,你知道他希望這個 json 數(shù)據(jù)是什么樣的形狀嗎?不知道。我現(xiàn)在看了代碼之后,可以給你講,它里面會有會有 Age、Name、Job、Address。
看一下 Age,它需要能夠使用 Int,那應(yīng)該是個整數(shù),但是要看代碼才知道,再下面還是簡單,那你們覺得 Name 的值是什么東西?完全沒有使用到,它是一個 String,它是不是姓和名放在一起了?還是放在一個 Vector 里面,可能姓和名是分開的,就是說不知道,要看代碼才知道。
你看到代碼之后覺得,原來是這樣,它應(yīng)該是一個 Vector,或者是 List,姓和名是分開放,因為它這系,它用空格來 Join 一下,這個是一個很淺顯的例子,就已經(jīng)說明了 Clojure 的動態(tài)靈活性非常強,但是也造成對數(shù)據(jù)的解釋性標記不是很清楚。
前文是一個很淺顯的例子,現(xiàn)在來看一個更具體的。為了這個主題我想了好幾天,覺得還是寫一個很小的項目來展示一下要講的東西。那寫什么東西呢?我又想了好幾天,在此先謝謝鏈家。因為是這樣的,既然要來北京,就要關(guān)注一下房價。我到網(wǎng)上去看二手房信息,但一頁頁翻過去很累,我不可能手寫一個總結(jié),于是就寫點程序抓取。當然這里不是真的寫了一個爬蟲,只是抓幾個頁面做做樣子,沒有讓鏈家服務(wù)受到傷害,請鳥哥放心。
命名空間做的基本上就是通過一個庫把 html 讀進來之后,進行一些簡單的操作,把整理好的數(shù)據(jù)寫到一個 EDN 文件里邊。比如說第一條你可以看到這個小區(qū) 1150 萬,三臥室兩個客廳,一個廚房兩個衛(wèi)生間,包括面積之類的東西。再看這個數(shù)據(jù)轉(zhuǎn)換的函數(shù),它收到一個參數(shù)是 Page,但這個 Page 長什么樣完全不知道。我是通過庫讀進來的,讀進來之后,并不知道它長什么樣子,現(xiàn)在看這個代碼也很難知道,它到底會返回一個什么樣的類型,什么樣的數(shù)據(jù),如果將來需要擴展的話,或者將來我要給另外一個人用,或者幫助另外的一個人去做一些擴展,做一些維護很難搞定。
這就是前文說的 Clojure 作為一個動態(tài)語言的弊端——太靈活。這個弊端導(dǎo)致經(jīng)常會忘記函數(shù)的參數(shù)是什么樣子,而且這個是小項目,項目一大,那就更麻煩。可能有人會說的,文檔不就是做這個事情的嗎?文檔跟測試,沒有緊密的聯(lián)合在一起,文檔本身的代碼是剝離的,而相對代碼本身是沒有限制的。比如說很多代碼上面會寫,但是其實代碼里面并沒有,它可能起到的效果某種程度上也是挺有限的。
Core.typed
Core.typed 是一個類型系統(tǒng)。它和其他語言的類型系統(tǒng)還是有點不一樣的地方,不同點在于它不是語言的一部分,而是一個即查即用的庫。Lisp 的靈活性導(dǎo)致它能夠作為一個庫直接插進去,而不是要作為一個語言核心。因為它有宏,通過宏可以把一個很大的類型系統(tǒng)直接插進去,而且這個類型系統(tǒng)比一般的系統(tǒng)要靈活很多,主要體現(xiàn)在這幾個方面:
第一,它可以給已經(jīng)寫好的,沒有標注過的,或者說是用的庫里面沒有標注過的函數(shù)直接加上類型;
第二,不需要把所有函數(shù)全部加上類型,你不想要的話,就不需要;
第三,你即使加上了也不一定要進行類型檢查,所以它是一個選擇性非常強的東西。它是為了能夠和 Clojure 這樣的語言進行協(xié)作。
那我們現(xiàn)在看一下它支持什么東西:
OptionType,現(xiàn)在很流行,這個流行的語言現(xiàn)在都有這個結(jié)構(gòu)。
Ordered Intersection Type 這個我不多講了,這個就是說一個函數(shù),比如有兩種參數(shù)形式,這兩種參數(shù)類型可能又不一樣,你再進行類型檢查的時候,它會把這個參數(shù)從上到下有序的來進行一個匹配。unionType,寫過 Haskell 人都知道,這個很簡單,比如說整數(shù),或者說是字符串,把它 union 一下,那就表示這個類型里面的東西可以是字符串,也可以是函數(shù)。
Identity 是很簡單的函數(shù),它會給你一模一樣的東西,那它的類型是什么呢?它這個函數(shù)的類型是什么東西呢?讓 Core.type 來幫我看一下。這個基本上可以看到前面有個 all,在這里對所有的 X 能取得的類型它返回的是一個 X,就是 Polymorphism 最簡單的一個體現(xiàn)了。Occurrence Typing 這個東西見到的比較少,它是什么呢?它是通過檢查代碼里面寫的控制流,比如像 if,或者像 switch,它能夠進行類型推導(dǎo)。
舉個例子,首先把這個 Form 綁到 A 這個名字上面,值就是 1,但是我把它標注成了 any,就是說這個 A,就算只是 1,然后再返回 A,這里大家覺得會返回什么東西?如果是檢查一個類型,它最后返回的是 A,它是什么類型?Any,因為我已經(jīng)標過了,我說 A 是 Any,所以它就相信 A 是 Any,但是如果我這么寫,這個會返回什么東西?你可以看到它現(xiàn)在還是返回的是 A,這個 A 或者這個也是 A,那其他情況返回的是 Nil,那他現(xiàn)在覺得這個東西是什么呢?還是不是 Any,因為你現(xiàn)在有了控制流在這邊,代碼里已經(jīng)寫過了,所以它知道你只可能是 number,或者是 string,要不然就是 nil,所以最后 A 是 union string/number/nil。這個東西功能上是非常強大的,這個也是我強推的一個東西,這個你真正用起來就知道方便。
最后一個就是宏也會被展開之后再推導(dǎo)類型,宏跟大家剛剛知道的 switch 有點像,就是已經(jīng)很直接了當?shù)模嬖V大家這個宏是可以展開之后判斷類型。我做的 Demo 的 types Demo,就是把剛剛鏈家那個小項目加了類型系統(tǒng),我現(xiàn)在是把它所制造的結(jié)果定義類型,但它其實是什么呢?是一個 Map。
Core.spec 總結(jié)
通過一個庫給動態(tài)語言加上類型系統(tǒng)——即插即用
可以給已經(jīng)寫好的函數(shù)或者是用的無類型庫標注類型
可以選擇性地加上類型
加上了類型也并非一定要 type check
支持 Option Type,Ordered Intersection Types, Union Types
支持 Heterogenous Maps 和 Sequentials
支持 Polymorphism (All, Context Bounds),Higher-Kinds
支持 Occurrence Typing!(通過檢查 control flow 進行類型推導(dǎo))
宏也會被展開后再推導(dǎo)類型
Core.spec
我本人很喜歡寫這個,我覺得給函數(shù)加上類型非常過癮,但是有問題,那有別的辦法嗎?有的,Core.spec,現(xiàn)在這個東西是 Clojure 核心,在很盡力地推廣。在方法上或者在函數(shù)上,加上先限條件,功能要強大一點,強大在什么地方呢?
比方說生產(chǎn)環(huán)境,Runtime 不會受到影響,它的性能不會受到影響。因為如果你一天到晚在檢驗,它的性能上是會受到影響的,所以缺省驗證是關(guān)閉掉的,如果你覺得某些東西可能重要性比較大,你要加上去也是可以的。spec 非常靈活,它可以把那種正則方式的 rule 給寫起來,就是比如某個 list,我覺得里面開頭至少有一個字符串,然后后面跟著的至少是 0 個的整數(shù)等等,你就可以用正則里面的加號,星號直接定義這個 rule。并且所有只有一個參數(shù)的 predicate 的函數(shù)統(tǒng)統(tǒng)可以跟它進行無縫對接,不需要另外語法把它轉(zhuǎn)換成 spec。這里面有很多種的驗證方式,那么多的驗證的方式可能現(xiàn)在沒有時間講,就不講了,總體來說就是可以把數(shù)據(jù)套在一個很靈活的模子里。
Core.spec 總結(jié)
Runtime 性能基本不會受到影響(缺省 spec 驗證關(guān)閉)
Map 的類型應(yīng)該就是 key 及其對應(yīng)的值的類型!(keys)
Sequence 可以多方面限制(cat, alt, regex style matching, coll-of)
只有一個參數(shù)的返回 boolean 值的函數(shù)通通都自動成為 predicate
各種驗證方式,滿足你的需求 (conform, explain, valid?)
multi-spec 支持更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
Core.type vs Core.spec
寫在最后
core.typed 和 core.spec 你推薦哪個?
我的腦子喜歡 core.spec,因為有前景。我的內(nèi)心喜歡 core.typed,因為給東西加類型寫起來真得很過癮。
寫《程序員修煉之路》的 Andy Hunt 和 David Thomas 大師曾說,要在軟件開發(fā)這個行當立于不敗之地,應(yīng)該“每年學(xué)一種新的語言”。10 月 QCon 上海站上,C++ 之父 Bjarne Stroustrup會分享關(guān)于 C++ 語言的發(fā)展和未來編程語言格局,還有摩根大通高級程序員趙劼(老趙)、阿里中心主管楊冠寶(孤盡)、PingCAP 首席架構(gòu)師唐劉、餓了么資深 Android 工程師張濤、滬江資深 Android 工程師何梁偉、Movoto 前端工程師吳名揚等,分享有關(guān) Kotlin、Rust、TypeScript、.Net 的語言實踐,也歡迎你到現(xiàn)場和我們交流。
點擊【閱讀原文】抵達 QCon 全球軟件開發(fā)大會,學(xué)習(xí) 2017 你想學(xué)習(xí)的新語言。如有任何問題可聯(lián)系購票經(jīng)理 Hanna ,電話:15110019061,微信:qcon-0410。
何婧譽(Loretta),Morgan Stanley VP。一枚劍橋大學(xué)計算機科學(xué)系畢業(yè)的妹子,興趣范圍從技術(shù)、數(shù)學(xué)、金融到桌游、國標、英文書法、語言學(xué)、哲學(xué)、鋼琴等范圍極廣,屬于樣樣都知道一些的典型 jack of all trades。技術(shù)上主要擅長 JVM 語言,有幾年 Java 經(jīng)驗,2010 年遇見 Clojure 之后頓時被其簡潔的語法、簡單的寫法及極具表達力的特性深深吸引,2011 年得以開始專業(yè) Clojure 5 年多,現(xiàn)于大摩寫 Scala。主要用 Clojure 做數(shù)據(jù)流處理,但也曾用其做過網(wǎng)絡(luò)應(yīng)用乃至安卓應(yīng)用。JVM 之外亦與 Python、Perl 等主流語言,以及 ML 等非主流函數(shù)語言打過交道。約四年前開始與國內(nèi)的 Clojure 社區(qū)有所接觸,業(yè)余時間致力于解答 Clojure 相關(guān)問題,并希望能將 Clojure 的影響范圍繼續(xù)擴大。
點擊下方圖片即可閱讀
百度正式開源其 RPC 框架 brpc
年我都會關(guān)注一下Stack Overflow的開發(fā)者調(diào)查,因為從中可以觀察到一些有趣的東西和業(yè)界的趨勢, 然后和自己的技能點比較一下,瑟瑟發(fā)抖或者心中竊喜一下......
2021年的調(diào)查有8萬多人參與,主要以歐美+印度為主, 中國程序員參與不多,也許是語言障礙吧。
70%的程序員年齡都在34歲以下,看來“35歲”是全世界程序員的魔咒
毫不意外, 男生占到了90%以上
最常用的編程語言
JavaScript繼續(xù)問鼎,這已經(jīng)是連續(xù)第九年排名第一了,用JavaScript做開發(fā)的人可真多啊!
讓我感到意外的是,Go語言排名居然這么低 !難道真是如網(wǎng)上所說,Go語言在中國的火爆程度超越外國?
最常用的數(shù)據(jù)庫
MySQL 依然排在榜首, PostgreSQL緊隨其后。
Oracle 怎么這么低?
SQL Sever怎么這么高?應(yīng)該是微軟Azure的功勞吧!
不過,開源軟件占據(jù)了統(tǒng)治性的地位!
最常用的Web框架
前端框架再次刷榜,別的框架都沒有“活路”了!
Spring排名真低!
我懷疑這是因為前端程序員參與調(diào)查的人比較多,后來看了看開發(fā)人員的類別調(diào)查,有近一半的人選了全棧程序員,他們肯定也會選前端框架,于是把前端框架拉高了吧。
最常用的IDE
Visual Studio Code 已經(jīng)成神, Eric Gamma實在是牛逼,不知道他看到自己一手締造的Eclipse的排名會是什么感覺。
Visual Studio還是那么強勢,從上世紀90年代開始,微軟在開發(fā)工具上一直挺立潮頭。
注意一下Vim ,排名很高
最愛的和最想拋棄的編程語言
這是Stackoverflow調(diào)查最有趣的地方。
對于一門語言,如果你今年用了,明年還想用,就被劃分到“最愛的” 范疇。
如果你今年用了,但是明年不想用了,就被劃分到“最想拋棄的”范疇。
沒想到Rust, Clojure, Elixir, Julia 這些小眾語言有這么多人熱愛,它們身上肯定有與眾不同的東西。
大Java有近53%的人想拋棄它,慘!
估計是維護祖?zhèn)鞔a受不了了吧!
最想學(xué)習(xí)的語言
對于一門語言,如果你今年沒用,明年想用,就被劃分到“最想學(xué)習(xí)的”范疇。
Python名列榜首, 兩個Script緊隨其后。
我覺得我也應(yīng)該寫一個Python教程了。
收入最高的編程語言
終于來到激動人心的環(huán)節(jié) !
Clojure排名第一, 解決10萬美元!想不想學(xué)一下?但是估計職位不好找吧。
F#, Elixir, Erlang , Perl , Ruby緊隨其后。
這些都不是最常用的編程語言,看來小眾語言人才不好找啊。
收入最高的編程框架
Ruby on Rails居然排名第一!
Spring只能排名第9 。
收入最高的職業(yè)
收入高的除了管理人員,CXO,還有SRE,DevOps,Data工程師,意外吧?
不知道在中國是不是這樣,希望國內(nèi)也有知名的網(wǎng)站發(fā)動一下程序員,做一下類似調(diào)查,看看國內(nèi)的情況如何,如果已經(jīng)存在了,歡迎留言告訴我。
完整調(diào)查結(jié)果: https://insights.stackoverflow.com/survey/2021
個好的文本編輯器對于想要建立網(wǎng)站或進行編碼的任何人都是必不可少的。這對于習(xí)慣于面面俱到的環(huán)境的Mac開發(fā)人員而言更加明顯。對于他們來說存在一系列不同的優(yōu)質(zhì)軟件之選。今天小編將介紹幾款Mac上好用的HTML文本編輯器,對于每一款文本編輯器,小編將對對其中的亮點和不足之處進行了簡單的描述。
Atom(免費)
Atom被公認為Mac上最好的免費文本編輯器,以Node.js進行編寫,并嵌于GitControl中。它可以作為單純的Mac文本編輯器使用,也可以作為源代碼編輯器來使用。通過插件程序的使用,此應(yīng)用支持很多語言,如HTML, CSS, C/C++, Objective-C, Java, Go, C#, JavaScript, Python, PHP, Perl, XML, Mustache, Clojure, Ruby等等,使之成為了現(xiàn)代開發(fā)人員的有用工具。
其部分有用的功能包括多標簽編輯,自動完成,多面板組,一個文件系統(tǒng)瀏覽器,優(yōu)秀的導(dǎo)航選項,以及軟件包管理器。此外,Atom的一項非常重要的功能在于數(shù)以萬計的虛擬免費軟件包的可用性,其充分增強了它的功能性。
它的用戶界面非常友好,同時還提供一系列不同的主題可供用戶根據(jù)自己的喜好來選擇可視化環(huán)境。
一般而言,Atom可謂是明智之選,尤其是對于MEAN網(wǎng)頁開發(fā)人員而言。
Visual Studio(免費)
像Atom一樣,Visual Studio Code是一個功能強大的綜合應(yīng)用程序,可以作為HTML編輯器使用。VS Code是一款輕量級的文本和腳本編輯器,以擴展對插件的支持為概念,與Microsoft的功能強大的Visual Studio不會混淆。
有一些插件可用于在Code中編寫和運行Shell腳本,編寫Markdown文檔,甚至編寫AppleScript。那就對了; 您可以使用Microsoft的文本編輯器來創(chuàng)建僅在Apple計算機上運行的腳本。
但是輕量級的Visual Studio意味著對插件的依賴,但是它具有響應(yīng)能力,您不用在意那些永遠不會使用的功能。
MacVim (免費)
MacVim是一個將Vim程序員編輯器帶入Mac的項目。另一方面,Vim基于強大的Vi應(yīng)用程序,這是一個為Unix操作系統(tǒng)開發(fā)的文本編輯器。除了其他功能之外,MacVim應(yīng)用程序還支持使用熱鍵,包括全屏模式,允許您使用透明背景等等。
盡管Vim已內(nèi)置到操作系統(tǒng)中,仍有很多人對MacVim感興趣。它具有功能完整的菜單欄控件和比Apple維護的Vim更新的版本,對于新手來說,還算友好!
Sublime Text
Sublime Text是一款商業(yè)化的Mac文本編輯器。這款編輯器采用了Python應(yīng)用程序接口(API),并支持多種語言。此外,它的功能性通過插件的形式進一步予以強化,這些插件通常是由社團進行開發(fā)的,根據(jù)免費軟件許可予以開放使用。Sublime Text擁有超級友好的界面,有22種不同的主題可供選擇。在其眾多有趣功能當中有一項被稱為免分心模式,在該模式下,屏幕中心只包含文本。
其他的功能包括建立在簡單的JSON文件基礎(chǔ)之上的高級定制功能;以及分割編輯,也即編輯能夠在兩個不同的文件或一個文件的不同部分之間完成。簡單來說,它的快速文件和文本行導(dǎo)航,它的跨平臺支持,以及以項目為本的參數(shù)選擇,使得這款應(yīng)用經(jīng)常被評為“最佳Mac文本編輯器”。
TextMate
強大,簡單且輕巧的TextMate是許多Mac專業(yè)人士的首選,不難理解為什么。該編輯器支持多種語言和語法,選項卡以及特定于語言的方法,可以節(jié)省您的時間和精力。
TextMate包含摘要,宏和作用域確定功能,可在不逐步進入完整IDE范圍的情況下極大地加快工作流程。開發(fā)人員旨在將“ Apple的操作系統(tǒng)方法帶入文本編輯器世界”,這是為什么這么多人喜歡TextMate的一個很好的總結(jié)。
這是一個易于使用的簡單工具,界面簡潔,價格合理。盡管開發(fā)有時會停滯不前,但TextMate仍然堅持不懈地追隨專業(yè)用戶。
它是典型的Mac文本編輯器,與TextWrangler來自同一開發(fā)人員。盡管缺少Atom的新鮮度或Sublime Text中清晰的UI,但BBEdit是針對macOS從頭開始構(gòu)建的,針對該平臺進行了優(yōu)化,并采用Mac方式進行文本編輯。
這意味著對于普通的Mac用戶來說,鍵盤快捷鍵是有意義的,以及遵循Apple的許多設(shè)計敏感性的文本編輯方法。它還支持Bonjour等Mac技術(shù)。這消除了其他應(yīng)用程序中出現(xiàn)的一些進入障礙,但導(dǎo)致UI與其競爭對手相比更加笨拙。
BBEdit非常適合HTML和文本編輯,并支持通過FTP / SFTP進行遠程編輯。該應(yīng)用程序高度可定制,從語法著色到菜單選項,用戶定義的功能,鍵盤快捷鍵以及直接在該應(yīng)用程序中的macOS終端支持。
什么是最好的HTML文本編輯器?它不一定是功能最多的那個。但一定是最適合您工作方式的那一個。小編建議您在決定之前先進行一些測試,找到最適合自己的那款!
(來自Mac下載macz.com)
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。