成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Scala的類型系統(tǒng):取代復(fù)雜的通配符

原創(chuàng)
開發(fā) 后端
Scala是一種針對 JVM 將函數(shù)和面向?qū)ο蠹夹g(shù)組合在一起的編程語言。Martin Odersky創(chuàng)建這個(gè)語言之時(shí),希望它能夠解決Java語言中的一些問題。Scala現(xiàn)在還相對比較小眾,但也已經(jīng)擁有了相當(dāng)忠實(shí)的擁護(hù)群體。然而,很新的語法需要一段時(shí)間的適應(yīng)。Scala也面臨這樣的問題,尤其是在類型方面,還需要人們漸漸去適應(yīng)。

51CTO編輯推薦:Scala編程語言專題

【51CTO獨(dú)家特稿】上次我們講了Scala的類型系統(tǒng),講到了它的可擴(kuò)展性,它的Duck Typing類型推理功能,展示了在類型系統(tǒng)上它比Java更加的靈活。本文中,Martin Odersky將繼續(xù)講解Scala的類型系統(tǒng)。今天的內(nèi)容是映射Java通配符的Existential類型,類型的可變性,以及抽象類的功能。

Existential類型

Bill Venners:最近Scala中添加了一些Existential(存在)類型。我聽說添加Existential類型的理由是為了可以映射所有Java類型到Scala類型,特別是Java的通配符類型。Existential類型數(shù)量是否多于Java通配符類型?它們是否是Java通配符類型的一個(gè)擴(kuò)展集?是否存在其他人們應(yīng)該了解它的理由? 

Martin Odersky:這很難說,因?yàn)槿藗儾]有一個(gè)真正的關(guān)于什么是通配符概念。最初由Atsushi Igarashi和Mirko Viroli設(shè)計(jì)的通配符,其靈感來源于Existential類型。事實(shí)上,最初的論文中存在一個(gè)使用Existential類型的編碼。但后來當(dāng)實(shí)際最終設(shè)計(jì)在Java中實(shí)現(xiàn)時(shí),這種聯(lián)系就減少了一些。所以,現(xiàn)在我們真的不了解這些通配符類型的狀況。

Existential類型已經(jīng)出現(xiàn)許多年了,至今為止大約有20年左右。這種類型可以很簡單地表達(dá)信息。例如你有一個(gè)類型,也許是list(列表)類型,其中一個(gè)列表項(xiàng)的類型你不知道,你只知道它是一些特殊元素類型的列表,但你不知道元素的類型。在Scala中,這就可以表示成一個(gè)Existential類型。語法是List[T] forSome { type T }.。這看起來有點(diǎn)繁瑣。這種繁瑣的語法實(shí)際上是故意的,因?yàn)樗a(chǎn)生的Existential類型通常有點(diǎn)難以處理。現(xiàn)在,Scala有了更好的選擇。它并不需要這么多Existential類型,因?yàn)槲覀兛梢允褂冒渌愋统蓡T的類型。 

Scala需要Existential類型有3個(gè)本質(zhì)上的理由。首先,我們需要弄清一些Java通配符的意思,Existential類型就是我們所理解的意思。其次,我們需要弄清一些Java raw(原始)類型的意思,因?yàn)樗鼈內(nèi)蕴幱陬悗熘校莡ngenerified(非屬性的)類型。如果你使用一個(gè)Java原始類型,如java.util.List,這是一個(gè)列表,你不知道列表元素的類型。在Scala中這可以被表示成一個(gè)Existential類型。最后,我們需要使用Existential類型來解釋在虛擬機(jī)上發(fā)生著什么事情。Scala像Java一樣,使用泛型擦除模式,所以當(dāng)程序運(yùn)行時(shí),我們不再能看到類型參數(shù)。為了能與Java互用,我們需要進(jìn)行擦除操作。但是,當(dāng)我們做映射或想要表示時(shí),在虛擬機(jī)上會發(fā)生什么事情?我們需要能夠表達(dá)虛擬機(jī)在使用Scala中的類型時(shí)做了什么事情,Existential類型讓我們做到了這一點(diǎn)。Existential類型可以讓你在不了解類型中某些方面的情況下使用它們。

Bill Venners:您能舉一個(gè)具體的例子嗎? 

Martin Odersky:以Scala lists(列表)為例。我希望能夠描述方法的返回類型,head,它會返回列表第一個(gè)元素(頭一個(gè))。在VM水平,這是一個(gè)List[T] forSome { type T }。我們不知道T是什么。Existential類型理論告訴我們,這是一個(gè)適合某個(gè)類型T的T。這相當(dāng)于根類型——對象。因此,我們從head方法得到這個(gè)類型。因此在Scala中,當(dāng)我們知道某個(gè)類型時(shí),我們可以消除這些Existential限制。當(dāng)我們不知道某個(gè)類型時(shí),我們就可以使用Existential,Existential類型理論就是在這里給予我們幫助。 

Bill Venners:如果您沒有必要擔(dān)心與Java通配符、原始類型和擦除的兼容性,還會添加Existential類型嗎?如果Java擁有具體化的類型,沒有原始類型和通配符,那么Scala還會有Existential類型嗎? 

Martin Odersky:如果Java擁有具體化的類型,沒有原始類型和通配符,我認(rèn)為Existential類型的使用量就沒那么大了,那么我會考慮Scala不使用它。

可變性 

Bill Venners:在Scala中,是在定義類的時(shí)候定義可變性(variance),而在Java中,是在使用通配符的地方定義它。您能否談?wù)勥@一差異? 

Martin Odersky:由于我們可以在Scala中使用Existential類型建模通配符,實(shí)際上如果你想,你也可以在Java中做同樣的事情。但是,我們不鼓勵(lì)你這么做,而是建議使用定義地點(diǎn)可變性(definition site variance)來代替。這是為什么?首先,什么是定義地點(diǎn)可變性?當(dāng)你定義一個(gè)帶有一個(gè)類型參數(shù)的類時(shí),例如List[T],這就帶來了一個(gè)問題。如果你有一個(gè)蘋果列表,那么它同樣也是一個(gè)水果列表嗎?你會說,當(dāng)然是的。如果蘋果是水果的一個(gè)子類型,那么List[Apple]應(yīng)該是List[Fruit]的一個(gè)子類型。這種子類型關(guān)系被稱為協(xié)變(covariance)。但在某些情況下,這種關(guān)系并不有效。如果我有一個(gè)變量,變量可以保存一個(gè)蘋果,可以保存蘋果類型的一個(gè)引用。但,這不是水果類型的一個(gè)引用,因?yàn)槲也荒芊峙淙魏纹渌o這個(gè)變量,它只能是一個(gè)蘋果。所以,你可以看到,有些情況下我們應(yīng)該有子類型,而有些情況下,子類型就不應(yīng)該有。

Scala的解決方案是注釋類型參數(shù)。如果List在T上是協(xié)變的,我們就可以寫成List[+T]。這將意味著Lists在T上是協(xié)變的。當(dāng)然這存在一些附屬條件。例如,只有當(dāng)沒有人改變List的情況下,我們才可以這么做,否則我們將遇到使用引用時(shí)遇到的同樣問題。  

在Scala中會發(fā)生什么事,這是程序員說的,我認(rèn)為Lists應(yīng)該是協(xié)變的,這意味著尊重子類型關(guān)系。然后,程序員將會在聲明的地方,用一個(gè)加號修飾類型參數(shù)T,針對所有使用的List只修飾一次。然后編譯器將去找出是否List內(nèi)的所有定義都與其一致。如果存在某些與協(xié)變不符的地方,Scala編譯器將會提示錯(cuò)誤。Scala擁有一系列的技術(shù)來處理這些錯(cuò)誤,一個(gè)有能力的Scala程序員將會很快注意到這些錯(cuò)誤,并應(yīng)用這些技術(shù),最終生成一個(gè)錯(cuò)誤處理類。使用者就不必再去顧慮這些錯(cuò)誤了。他們只需知道如果我有一個(gè)List,我就可以在任何地方協(xié)變地使用它。因此,這意味著只有一個(gè)人在寫list類,只有他需要考慮有點(diǎn)難度的問題,但這也不至于太糟糕,因?yàn)榫幾g器會用錯(cuò)誤提示幫助他。 

相比之下,Java帶有通配符的方法意味著在類中你什么都做不了。你只是寫List﹤T>。然后,如果用戶想要一個(gè)協(xié)變list,他們不寫List﹤Fruit>,而是寫List﹤? extends Fruit>。所以這是一個(gè)通配符。問題是,這是用戶代碼。這些用戶通常都沒有類庫設(shè)計(jì)人員那么專業(yè)。此外,這些注釋間一個(gè)單一的不匹配將會帶來類型錯(cuò)誤。因此,難怪你會得到大量與通配符有關(guān)的非常棘手的錯(cuò)誤信息,我認(rèn)為這是Java泛型最重要的罪魁禍?zhǔn)住R驗(yàn)檫@種通配符的方法對于普通人來說確實(shí)是太復(fù)雜、太難于處理。 

可變性是當(dāng)你結(jié)合泛型和子類型時(shí)非常重要的東西,但它也很復(fù)雜。沒有辦法能完全讓它變成一件小事。我們做的比Java好的地方是,可以讓你只在類庫中做一次,使得用戶不需要考慮和處理它。 

抽象類

Bill Venners:在Scala中,一個(gè)類型可以是另一個(gè)類型的成員,就如同方法和域可以是一個(gè)類型的成員。在Scala中,這些類型成員可以是抽象的,就如同在Java中方法可以抽象。在抽象類型成員和泛型參數(shù)之間是否存在重疊?為什么Scala兩者都包含?抽象類型具有哪些泛型所不具有的功能?

Martin Odersky:抽象類型確實(shí)具有一些泛型所不具有的功能,但首先讓我陳述一個(gè)稍微普遍的原理。一直都存在兩個(gè)抽象概念:參數(shù)和抽象成員。在Java中,兩者都有,但它取決于你在抽象什么。在Java中你可以有抽象方法,但你不能把方法作為參數(shù)傳遞。你并不擁有抽象域,但可以傳值作為參數(shù)。同樣,你沒有抽象類型成員,但你可以指定一種類型作為參數(shù)。因此,在Java中你可以有以上3種方式,但使用什么抽象原則是有區(qū)別的。你可以爭辯說,這種區(qū)別是相當(dāng)武斷的。 

我們在Scala中所做的是力求更全面和垂直。我們決定對以上所有3種成員都采用同樣的構(gòu)造原則。所以,你可以有抽象域,也可以有值參數(shù)。你可以傳遞方法(或“函數(shù)”)作為參數(shù),或者也可以抽象它們。您可以指定類型作為參數(shù),或者也可以抽象它們。我們概念性地得到的是,我們可以按照其它的建模另一個(gè)。至少在原則上,我們可以表達(dá)各種參數(shù)為一種面向?qū)ο蟮某橄蟆R虼耍谀撤N意義上可以說Scala是一種更垂直、更全面的語言。 

現(xiàn)在,問題仍然存在,這能給你帶來什么好處?抽象類型是對以上我們談到的問題的很好的處理,一個(gè)已經(jīng)存在了很長一段時(shí)間的標(biāo)準(zhǔn)問題是動物和食物。讓人不解的是,有個(gè)動物類,帶有一個(gè)吃一些食物的方法。問題是,如果我們建立一個(gè)動物類的子類,如牛,那么它們將只吃草,而不是任意食物。例如,牛不會吃魚。你真正想要的是一個(gè)牛類,帶有一個(gè)只吃草而不吃其它東西的方法。實(shí)際上,在Java中你不能這樣做,如像前面提到的分配一個(gè)任意的水果給蘋果變量的問題。 

問題是,你怎么辦?答案是,你為動物類添加一個(gè)抽象類型。你說,新的動物類中含有一個(gè)SuitableFood(適當(dāng)食物)的類型,這我不知道。因此這是一個(gè)抽象類型。你并不給出類型實(shí)現(xiàn)。然后,你就可以有一個(gè)吃的方法,只吃適當(dāng)?shù)氖澄铩H缓笤谂n愔校視f,好吧,我有一個(gè)牛類,它繼承于動物類,并且對于牛類型來說,適當(dāng)?shù)氖澄锞褪遣荨R虼耍谧宇愔芯涂梢詫?shí)現(xiàn)這些抽象。 

現(xiàn)在,你可以說,我可以用參數(shù)完成同樣的事情。事實(shí)上,你確實(shí)可以。你可以給動物類添加參數(shù),參數(shù)為各種所吃的食物。但在實(shí)踐中,當(dāng)你要完成很多事情的時(shí)候,這就導(dǎo)致了參數(shù)爆炸,而且通常更重要的是,參數(shù)的范圍。在1998年的ECOOP ,Kim Bruce, Phil Wadler和我一起發(fā)過一個(gè)文章,我們指出,隨著你增加你所不知道的東西的數(shù)量,典型的程序?qū)?次方程式的數(shù)量增加。因此,我們有理由盡量不用參數(shù),而是使用抽象成員。 

適應(yīng)新的語法

Bill Venners:當(dāng)人們隨機(jī)查看Scala代碼時(shí),我認(rèn)為有兩件事可以使它看上去有點(diǎn)神秘。一個(gè)是DSL是他們不熟悉的,就像是解析器或XML類庫。另一個(gè)是類型系統(tǒng)的各種各樣的表達(dá)式,特別是表達(dá)式的聯(lián)合。Scala程序員如何能掌握這樣的語法? 

Martin Odersky:當(dāng)然這里存在很多新東西,必須進(jìn)行學(xué)習(xí)和吸收。因此,這將花費(fèi)一些時(shí)間。我相信我們需要繼續(xù)努力研究的一件事是更好的工具支持。現(xiàn)在,當(dāng)你獲得類型錯(cuò)誤時(shí),我們試圖給你一個(gè)不錯(cuò)的錯(cuò)誤信息。有時(shí)候,錯(cuò)誤信息有很多行,能夠解釋得更好。我們盡力做好,但我認(rèn)為如果我們能有更好的交互性,我們將可以做的更好。

試想一下,如果有一個(gè)動態(tài)類型語言,對于一個(gè)錯(cuò)誤信息,只有3到4行的錯(cuò)誤提示。可能不會有調(diào)試器,不會有堆棧跟蹤,只有3到4行提示信息,如“空指針廢棄,”也許會有發(fā)生錯(cuò)誤的行號。在這種情況下,我不認(rèn)為動態(tài)語言會是非常受歡迎的。當(dāng)然,這不是真實(shí)發(fā)生的事情。實(shí)際上,你擁有一個(gè)調(diào)試器,可以讓你快速找到錯(cuò)誤根源。 

對于類型,我們還沒有這些設(shè)施。我們所有的只是一些錯(cuò)誤信息。如果你有一個(gè)非常豐富和富有表現(xiàn)力的類型系統(tǒng),它需要更多的知識來理解這些錯(cuò)誤信息,你想要更多幫助。因此,在未來我們要研究的一件事是,我們是否能夠真正給你一個(gè)更具有互動性的環(huán)境,例如,如果類型出現(xiàn)問題,你可以找出錯(cuò)誤原因。例如,如何讓編譯器指出這個(gè)表達(dá)式的類型應(yīng)該是這個(gè),以及它為什么不認(rèn)為這個(gè)類型符合其它預(yù)期類型。你可以交互式探索這些東西。如果這樣,我想,由于類型所導(dǎo)致的錯(cuò)誤將能夠更容易被發(fā)現(xiàn)。

另一方面,一些語法很新,需要一段時(shí)間的適應(yīng)。這也許是我們無法避免的。我們只希望在今后兩三年內(nèi),人們將能夠完全熟悉這些類型。其他的一些主流語言在剛推出時(shí)也遇到過類似問題。我非常清楚地記得,當(dāng)異常捕獲語句剛出現(xiàn)時(shí),人們就覺得它很奇怪,花了很長時(shí)間來適應(yīng)。當(dāng)然,現(xiàn)在每個(gè)人都認(rèn)為這是很自然的。Scala也面臨這樣的問題,尤其是在類型方面,還需要人們漸漸去適應(yīng)。

【相關(guān)閱讀】

  1. Scala的類型系統(tǒng) 比Java更靈活
  2. Java程序員,你為什么要關(guān)注Scala
  3. Scala創(chuàng)始人:創(chuàng)造比Java更好的語言
  4. Java以外的選擇 Scala編程語言簡介
  5. Java之外,選擇Scala還是Groovy?
責(zé)任編輯:yangsai 來源: 51CTO.com
相關(guān)推薦

2009-06-03 09:08:20

ScalaJava類型

2009-07-22 09:43:30

Scala類型

2009-12-11 10:45:00

Scala講座類型系統(tǒng)功能

2009-07-21 09:31:00

Scala基本類型文本

2009-07-09 00:25:00

Scala參數(shù)化

2020-10-31 17:33:18

Scala語言函數(shù)

2009-07-08 12:43:59

Scala ServlScala語言

2022-01-13 09:49:40

遺留系統(tǒng)交接開發(fā)

2009-07-10 15:37:08

ScalaFan函數(shù)式編程

2009-07-22 09:53:57

Scala底層類型

2010-09-14 15:34:41

Scala

2012-09-06 14:54:58

Linux集群

2018-11-29 09:36:45

架構(gòu)系統(tǒng)拆分結(jié)構(gòu)演變

2013-08-15 10:23:03

LinuxUnix操作系統(tǒng)

2017-05-16 14:31:09

2009-11-16 17:04:46

Inside Scal

2022-02-22 10:11:01

系統(tǒng)軟件架構(gòu)

2010-05-12 10:19:14

英特爾安騰謎局

2013-03-29 09:15:15

移動瀏覽器HTML5手機(jī)操作系統(tǒng)

2009-10-19 11:26:08

Scala循環(huán)數(shù)組
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美性影院 | 一级日韩 | 精品欧美乱码久久久久久1区2区 | 色吧久久| 久久精品av麻豆的观看方式 | gav成人免费播放视频 | 亚洲a视频 | 99久久精品国产毛片 | 日韩欧美在线一区 | 日韩欧美一区二区三区免费观看 | 北条麻妃国产九九九精品小说 | 玩丰满女领导对白露脸hd | 黑人巨大精品 | 可以在线看的黄色网址 | 天天艹逼网| 久久久久久久夜 | 一区二区在线看 | 国产精品性做久久久久久 | 日本精品一区二区 | 午夜视频在线 | av免费在线播放 | 99精品免费视频 | 久久国产精品视频 | 91在线观看视频 | 国产福利资源在线 | 国产乱一区二区三区视频 | 久久久久久免费毛片精品 | 在线成人免费视频 | 日本视频在线 | 91av在线电影 | 一区二区三区免费网站 | 欧美精品影院 | 手机三级电影 | 激情五月婷婷在线 | 天天看天天爽 | 国产精品视频久久 | 精品一区二区久久久久久久网站 | 视频三区 | 国产区精品 | 欧美黄色小视频 | 日韩福利电影 |