Ruby高手點評Scala編程語言十大絕招

原文地址

【51CTO精選譯文】幾個月前鉴逞,我開始使用 Scala。我用過的編程語言還有 Pascal司训、C构捡、C++、Java壳猜、PHP勾徽、Ruby 和 Groovy,但是统扳,與所有那些我用過的語言相比喘帚,我發(fā)覺 Scala 是一門與眾不同的語言。我是在看到 Twitter 上關(guān)于 Ruby 和 Scala 討論之后咒钟,才開始我的 Scala 編程之旅的〈涤桑現(xiàn)在,使用 Scala 編程已經(jīng)幾個月了朱嘴,關(guān)于 Scala 我有兩點想法倾鲫,雖然類似的想法已廣為人知,但我仍很想與你們分享:

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

◆Scala 的確很棒萍嬉。
◆我的確認(rèn)為計算機(jī)學(xué)院應(yīng)該開一門 Scala 的語言課程乌昔。
在這篇文章中,我會講述為什么我會有這樣的想法帚湘,在此之前玫荣,有幾點我想要先聲明一下:
本文無意對編程語言進(jìn)行評比,我要講述的主體是為什么你應(yīng)該學(xué)習(xí) Scala大诸。
51CTO之前曾發(fā)布過一篇 Java 程序員為何要學(xué)習(xí)Scala的文章捅厂,可能也會對你有所幫助。
目前 Scala 有兩個實現(xiàn)方式资柔,一種是在 JVM(Java 虛擬機(jī))上運行焙贷,另一種是在 CLR(Common Language Runtime 的縮寫,即公共語言運行庫)上運行贿堰。不過辙芍,JVM 的實現(xiàn)方式更為成熟。如果你想要使用 .Net framework 框架,我認(rèn)為最好還是聽從 Lift framework 框架創(chuàng)始人大衛(wèi)·波拉克(David Pollack)的建議:使用 F#故硅。但在這篇文章中庶灿,我將只關(guān)注 JVM 這種實現(xiàn)方式。
我是一個 Ruby 程序員吃衅,并且我會繼續(xù)喜歡 Ruby往踢,因為它是我見到過的最棒的動態(tài)語言。但我也喜歡 Scala徘层,因為在其他工作領(lǐng)域峻呕,它提供的某些功能非常強(qiáng)大。
現(xiàn)在趣效,讓我們來仔細(xì)分析一下瘦癌,是哪些原因讓我選擇 Scala 作為我的下一個編程語言:

強(qiáng)大的編程語言
Scala 是一門非常強(qiáng)大的語言,它允許用戶使用命令和函數(shù)范式進(jìn)行編寫代碼跷敬,因此讯私,編程時你可以使用常用的命令式語句,就像我們使用 C干花、Java妄帘、PHP 以及很多其他語言一樣,而且池凄,你也可以使用類似 Lisp 語言中函數(shù)式語句,還有鬼廓,你可以混合使用這兩種風(fēng)格的語句肿仑,就像 Ruby 或 Groovy。

不過碎税,當(dāng)我們談?wù)摰暮瘮?shù)范式時尤慰,與 Ruby 和 Groovy 有一點不同的地方,那就是 Scala 幾乎支持函數(shù)語言中所有已知的功能雷蹂,比如伟端,模式匹配(Pattern matching)、延遲初始化(Lazy initialization)匪煌、偏函數(shù)(Partial Function)责蝠、不變性(Immutability),等等...即是說萎庭,認(rèn)識到這樣一個事實是非常重要的:Scala 的強(qiáng)大源自它對函數(shù)范式的支持霜医,而后者令 Scala 成為一種高等級(high-level)的編程語言。對于高等級的編程語言驳规,你只需關(guān)注 what(做什么)而不是如何做(how)肴敛。
下面,讓我們看一個 Java 示例:

    int[] x = {1,2,3,4,5,6};   
    ArrayList res = new ArrayList();   
    for (int v : x) {   
        if (v % 2 == 1) res.add(new Integer(v));   
    } 

仔細(xì)看一下上面這段示例代碼,你會注意到医男,我想要做的“what”部分(過濾掉奇數(shù)值)僅出現(xiàn)在第四行中砸狞,而其余行則是“how”如何做的部分(結(jié)果變量的初始化以及一個循環(huán)操作)。如果我想要再寫一個過濾器镀梭,用于篩選偶數(shù)值趾代,那就需要再寫五行代碼,而使用一門像 Scala 這樣的高等級語言丰辣,你只需編寫“what”那部分的代碼:

    val x = Array(1,2,3,4,5,6)   
    val res = x filter ( _ % 2 == 1 ) //過濾奇數(shù)值
    val res2 = x filter ( _ % 2 == 0 ) //過濾偶數(shù)值

我們可以看到撒强,相對于上文中的 Java 代碼段,這段代碼更加簡潔笙什,而且具有更好的可讀性飘哨。

高效
Scala 是一種高效的編程語言,實際上琐凭,根據(jù)最新的 benchmark 性能測試芽隆,它幾乎和 Java 一樣快捷。在 JVM 上實現(xiàn)的 Scala 代碼统屈,可以編譯為字節(jié)碼胚吁,在這一過程中,代碼通過優(yōu)化階段進(jìn)行編譯愁憔。尾遞歸優(yōu)化是一個很好的示例腕扶,它可幫助用戶專注于函數(shù)范式而無需以犧牲性能為代價。還有一個示例是吨掌,將 Scala 值類型對象轉(zhuǎn)換為 Java 基本類型時進(jìn)行的優(yōu)化半抱。

可擴(kuò)展
Scala 語言本身的名字 Scala 來自 Scalable(可擴(kuò)展的)一詞,這意味著這種語言可以按照用戶的需求進(jìn)行擴(kuò)展膜宋。因此窿侈,從根本上來講,用戶可以添加新的類型和控制結(jié)構(gòu)秋茫。比如史简,我想要添加一個簡單的“l(fā)oop”控制結(jié)構(gòu):

    // 一個簡單的構(gòu)建
    def loop(range: Range)(op: Int=> Unit) {  
       range foreach (op)   
    }     
    loop(1 to 5 ){println} // 1 2 3 4 5 
    loop(1 to 5 ){x => if(x % 2 == 0) println(x)} // 2 4

還有幾個更為復(fù)雜的例子,Actor lib肛著,它是作為擴(kuò)展被添加到 Scala 這一語言中的圆兵,我們將在下文中對它展開討論。
不過策泣,Scala 之所以是可擴(kuò)展的衙傀,在于互相關(guān)聯(lián)的兩點:它是真正的面向?qū)ο蟮恼Z言和真正的函數(shù)式語言。

面向?qū)ο?/strong>
Scala 中每個事物都是對象(對象的方法除外)萨咕,因此统抬,沒有必要對基本(primitive)類型或引用類型進(jìn)行區(qū)分,這就是所謂的:統(tǒng)一對象模型(Uniform Object Model)。但是聪建,正如我之前在優(yōu)化流程中所提到的钙畔,值類型對象被轉(zhuǎn)換為 Java 基本類型,因此不必?fù)?dān)心性能的問題金麸。其內(nèi)部還包含為類方法分組的單件對象(Singleton object)擎析。
◆所有操作都是方法調(diào)用,+ - * ! / 都是方法挥下,因此揍魂,沒有必要進(jìn)行操作符重載。
◆非常精細(xì)的訪問控制棚瘟,用戶可以控制對某些包的某些方法的訪問现斋。
◆Scala 具有 trait,與 Ruby 中的 mixin 類似偎蘸,就像 Java 中的 interfaces庄蹋,但實現(xiàn)了某些它們的方法,因此迷雪,用戶在箱體(box)之外擁有富封裝器(wrapper)和富交互接口(interface)限书。

函數(shù)式語言
函數(shù)式語言具有很多特點,不過在擴(kuò)展性這一語境中章咧,我們所關(guān)心的是兩個事實:
◆函數(shù)是第一等級(first-class)的值
這表示用戶可以將函數(shù)作為值傳遞倦西,也可以作為值返回。這樣可以獲得簡潔而具有可讀性的代碼慧邮,正如上文中作為示例的過濾代碼段调限。

◆純函數(shù)(pure function)
Scala 支持沒有副作用的純函數(shù),這意味著:如果你的輸入相同误澳,那么輸出結(jié)果也總是相同。這樣能夠讓代碼更為安全秦躯,對代碼測試也更為方便忆谓。
但是,Scala 是通過什么方式來支持純函數(shù)的呢踱承?通過不變性(immutability):偏向固定的引用(與 java 中的 final 或其他語言中的 constant 類似)以及具有不變的數(shù)據(jù)結(jié)構(gòu)倡缠,一旦創(chuàng)建便不可修改。
不變性是擁有純函數(shù)的安全保證茎活,但并不是唯一的方式昙沦。沒有不變性,你仍然可以編寫安全的代碼载荔。這就是為什么 Scala 不是強(qiáng)制推行不變性而只是鼓勵使用它盾饮。最終,你會發(fā)現(xiàn) Scala 中許多數(shù)據(jù)結(jié)構(gòu)具有了兩種實現(xiàn)方式,一種是可變的丘损,另一種是不可變的普办,不可變的數(shù)據(jù)結(jié)構(gòu)是缺省導(dǎo)入的。
每當(dāng)提到不變性時徘钥,有人就會開始擔(dān)心性能的問題衔蹲,對于某些情況,這種擔(dān)憂并非毫無來由呈础,但對于 Scala舆驶,最終結(jié)果卻與這一擔(dān)憂相反。不可變的數(shù)據(jù)結(jié)構(gòu)相對于可變的數(shù)據(jù)結(jié)構(gòu)而钞,更有助于獲得較高的效率沙廉。其原因之一在于強(qiáng)大的垃圾收集器(garbage collector),與 JVM 中的垃圾收集器類似笨忌。

更佳的并行模型
當(dāng)涉及到線程這一問題時蓝仲,Scala 支持傳統(tǒng)的 shared data 模型。但是官疲,使用這種模型較長一段時間之后袱结,許多人發(fā)現(xiàn)使用這種模型編寫代碼,非常難以實現(xiàn)以及進(jìn)行測試途凫。你總是需要考慮死鎖問題和競爭條件垢夹。因此,Scala 提供了另一個稱為 Actor 的并行模型维费,其中果元,actor 通過它的收件箱來發(fā)送和接收非同步信息,而不是共享數(shù)據(jù)犀盟。這種方式被稱為:shared nothing 模型而晒。一旦你不再顧慮共享數(shù)據(jù)的問題,也就不必再為代碼同步和死鎖問題而頭痛阅畴。
被發(fā)送信息的不變性本質(zhì)以及 actor 中串行處理倡怎,這兩者使得對于并行的支持更為簡便。
有關(guān) Scala 并行的問題贱枣,請參閱這篇文章监署,對于這個概念你會有更好的理解。
在講述下一個要點之前纽哥,我需要提到這樣一個事實钠乏,一些人將 Actor 的使用視為編程語言的一種進(jìn)化。正如春塌,Java 的出現(xiàn)晓避,將程序員們從指針和內(nèi)存管理的泥淖中拯救出來一樣簇捍,Scala 的到來,讓程序員們不必再為代碼同步以及共享數(shù)據(jù)模型整天苦思冥想够滑。

靜態(tài)類型
當(dāng)我想要講述這一要點的時候垦写,才發(fā)現(xiàn),對于靜態(tài)類型語言的正反兩面彰触,我試圖給予同樣的關(guān)注梯投。事實上,關(guān)于這一話題的爭論總是沒完沒了况毅,但我要作出兩點總結(jié)分蓖,而這兩點是大多數(shù)人討論的熱點:
◆使用靜態(tài)類型語言編寫的代碼更加健壯(robust)
TDD 的存在,讓許多關(guān)于動態(tài)類型語言和健壯代碼的討論失去了意義尔许,雖然這是正確的,當(dāng)我們?nèi)匀徊荒芎鲆曔@樣一個事實:對于動態(tài)類型語言味廊,你需要編寫更多的測試代碼來檢查類型蒸甜,而在靜態(tài)類型語言中,你可以將這些問題交給編譯器處理余佛。此外柠新,還有一些人認(rèn)為,使用靜態(tài)類型語言辉巡,你的代碼將具有更好的自我記錄恨憎。
◆使用靜態(tài)類型語言編寫的代碼過于嚴(yán)格和冗長
像我這樣的動態(tài)類型語言的粉絲,認(rèn)為通過鴨子類型(duck typing)可以寫出更具動態(tài)性的代碼結(jié)構(gòu)郊楣。但同時他們還會抱怨憔恳,靜態(tài)類型語言導(dǎo)致代碼冗長。
關(guān)于靜態(tài)類型與動態(tài)類型的爭論净蚤,在51CTO之前發(fā)布的這篇文章中可以看到更多信息钥组。
作為靜態(tài)類型語言,Scala 具有第一條中提到的優(yōu)點今瀑,但是者铜,第二點呢?
Scala 具有一個靈活的類型系統(tǒng)放椰,并且可能是這一類型中最好的。很多情況下愉粤,如果你沒有指定類型砾医,這一系統(tǒng)將能夠?qū)︻愋瓦M(jìn)行推斷。
例如衣厘,你可以這樣編寫代碼:

    val list: List[String] = List("one", "two", "three")   
    //list: List[String] = List(one, two, three)    
    val s: String = "Hello World!"   
    //s: java.lang.String = hello world!
``` 

但你也可以這樣編寫代碼:
```
val list = List("one", "two", "three")   
//list: List[String] = List(one, two, three)    
val s = "Hello World!"   
//s: java.lang.String = hello world!
``` 

非常好如蚜,無論如何压恒,它解決了代碼冗長的問題。但像鴨子類型(duck typing)那樣的問題错邦,會怎樣呢探赫?
答案還是:Scala 的類型系統(tǒng)具有的某些靈活性,可以讓你編寫如下的代碼:
```
    def eat[T <: Animal](a: T) // whatever
```

其中撬呢,我們將類型 T 定義為 Animal 的子類型伦吠。還可以更加靈活:
```
   def eat[T <: {def eat(): Unit}](a: T) // whatever
```

其中,我們將類型 T 定義為一個具有非法  eat 的類型魂拦。
事實上毛仪,Scala 的類型系統(tǒng)非常豐富,你可以在這里找到更多信息芯勘。

**模式匹配**
我必須坦白箱靴,在猶豫良久之后,我才決定寫一寫 Scala 的這一特點荷愕。事實上衡怀,我本來沒有打算討論 Scala 的函數(shù)功能,但看到一篇有關(guān)對象分支(switch)應(yīng)用的文章后安疗,我想抛杨,還是有必要聊聊這個特點。以下內(nèi)容基本上都來自這篇博客文章:
模式匹配究竟是用來做什么的茂契?它讓你可以將一個值對多種情況(case)進(jìn)行匹配蝶桶,有點類似 Java 中的分支(switch)語句。但它不是僅僅匹配數(shù)字(這是分支語句的作用)掉冶,而是用戶能夠?qū)Ρ举|(zhì)上為對象創(chuàng)建形式(creation form)的事物進(jìn)行匹配真竖。

以下示例也來自上文提到的博客:
```
    x match {   
        case Address(Name(first, last), street, city, state, zip) => println(last + ", " + zip)   
        case _ => println("not an address") // 缺省情況  
    } 
```

對于第一種情況,模式 Name(first, last) 嵌套在模式 Address(…) 中厌小。 其中的 last 值恢共,被傳遞到 Name 構(gòu)造函數(shù),然后進(jìn)行提取璧亚,因此在箭頭右側(cè)的表達(dá)式中是可用的讨韭。

***模式匹配的意義***
*為什么你需要模式匹配?我們都會有復(fù)雜的數(shù)據(jù)癣蟋。如果我們堅持嚴(yán)格的面向?qū)ο缶幊掏赶酰敲次覀兙筒辉溉リP(guān)注數(shù)據(jù)樹的內(nèi)部情況。相反疯搅,我們想要調(diào)用方法濒生,讓方法來做這些事情。如果我們有能力完成這件事幔欧,就不會非常需要模式匹配罪治,因為方法滿足了我們的要求丽声。但是,很多時候?qū)ο鬀]有我們所需的方法觉义,并且我們不能(或不愿)為對象添加新的方法雁社。*
因此,模式匹配被認(rèn)為是一種獲得擴(kuò)張性的有效方法晒骇,并且霉撵,它還為該問題提供了一種不錯的解決方案,訪問者設(shè)計模式所導(dǎo)致的冗長除外厉碟。
不管怎樣喊巍,強(qiáng)烈推薦你看看上面所提到的文章中”擴(kuò)展性的兩個方向“(Two directions of extensibility)那個小節(jié)。

**簡單的 DSL(特定領(lǐng)域語言)**
編寫 DSL箍鼓,Scala 是一個很好的選擇崭参。事實上,Scala 適用于內(nèi)部和外部 DSL款咖。在這篇文章中何暮,你可以找到一些使用 Ruby 和 Scala 編寫內(nèi)部 DSL 的特點比較。下面這篇文章也很棒铐殃,是關(guān)于使用 Scala 編寫內(nèi)部 DSL 的:Boolean Algebra Internal DSL in Scala (aka fun with Unicode names )海洼。

此外,對于外部 DSL富腊,Scala 也應(yīng)該是首選語言坏逢,背后的原因是解析器組合子庫(parser combinator lib),它讓為新語言編寫編譯器成為一件很酷的事赘被。
**與 Java 代碼之間的互操作性**
在 JVM 上的實現(xiàn) Scala 的程序可以無縫地與 Java 平臺整合是整,很多 Scala 類型實際上都編譯為 Java 類型,因此民假,用戶可以放心地使用 Java 類型浮入。而且,你也可以混合地使用 JVM 語言來編程羊异,如:JRuby事秀、Groovy、Clojure 等野舶。這里有一篇不錯的文章易迹,提供了這種示例。

**學(xué)習(xí)型語言**
我有兩個習(xí)慣平道,在 Scala 的學(xué)習(xí)過程中赴蝇,我堅持了這兩個習(xí)慣:
◆遇到新的技術(shù)術(shù)語,訪問維基百科巢掺,理解更多信息句伶;比如 Function literal(文本函數(shù))、Referentially transparent(引用透明度)陆淀、Partial function(偏函數(shù))考余、Currying(科里華),還有很多其他術(shù)語轧苫。
◆參考我對其他語言的理解楚堤,檢查這些術(shù)語的涵義是否實現(xiàn)。
通過一些好的練習(xí)含懊,如編寫沒有副作用的純函數(shù)身冬,將精力集中在代碼中的“what”部分,而將“how”的部分交給語言處理岔乔;這兩個習(xí)慣讓我獲得更多知識酥筝,也提高了代碼的質(zhì)量。

**團(tuán)隊**
Scala 由馬丁·奧德斯基(Martin Odersky)設(shè)計雏门,他是瑞士聯(lián)邦理工學(xué)院洛桑分校(EPFL)編程方法實驗室小組的管理者嘿歌。奧德斯基曾受雇于 Sun 公司編寫 Java 1.1 編譯器,他還是 Java 1.1 到 Java 1.4 的 Javac 主要開發(fā)者茁影。此外宙帝,他還是 Java Generics 的提出者。51CTO編輯曾通過電子郵件與奧德斯基就 Scala 的語言特性進(jìn)行了交流募闲,并得到了回復(fù)信件[如下](http://developer.51cto.com/art/200906/128037.htm)步脓。
Scala 現(xiàn)在由奧德斯基和他在瑞士聯(lián)邦理工學(xué)院洛桑分校的團(tuán)隊維護(hù)。不過浩螺,還有其他一些具有才華的開發(fā)者參與靴患,通過多年的工作,他們共同打造出了 Scala 這一編程語言年扩。

**來源**
Scala 受到了[多種語言的啟發(fā)](http://developer.51cto.com/art/200907/134890.htm):
◆大多數(shù)的句法來自 Java 和 C#蚁廓。
◆其他一些元素也來自 Java,比如:基本類型(basic type)厨幻、類庫相嵌,以及其運行模型。
◆它所用的統(tǒng)一對象模型是由 Smalltalk 最先使用的况脆。
◆通用嵌套(universal nesting)的理念也出現(xiàn)在 Algol饭宾、Simula 中,而且最近還出現(xiàn)在 Beta 和 gbeta 中格了。
◆函數(shù)式編碼的方法在精神上也與 ML 語言家族類似看铆,該語言家族中包含 SML、OCaml盛末,以及最主要的成員 [F#](http://developer.51cto.com/art/200906/130786.htm)弹惦。
◆Scala 標(biāo)準(zhǔn)庫中的許多較高階的函數(shù)否淤,也出現(xiàn)在 ML 和 Haskell 中。
◆Scala 的隱式參數(shù)也是受到 Haskell 類型類的啟發(fā)棠隐。Scala 基于 actor 的并行庫主要是受到 Erlang 的啟發(fā)石抡。
◆將插入(infix)操作符視為函數(shù),以及允許文本函數(shù)(或 block 區(qū)塊)作為參數(shù)助泽,以使庫能夠定義控制結(jié)構(gòu)啰扛,這些特定的理念可以回溯至 Iswim 和Smalltalk。

**專家觀點**
實際上嗡贺,像詹姆士·斯特拉坎(James Strachan:編程語言 Groovy 的創(chuàng)始人)的[這樣的言語](http://developer.51cto.com/art/200907/134785.htm)讓人感到有點驚喜:
說實話隐解,如果有人在 2003 年給我一本由馬丁·奧德斯基(Martin Odersky)、萊克斯·斯彭(Lex Spoon)和比爾·文納斯(Bill Venners)合著的《Programming in Scala》诫睬,我很可能不會再去創(chuàng)建 Groovy煞茫。

在結(jié)束之前,我做一下總結(jié):
我喜歡 Scala岩臣,因為它是高效的溜嗜、學(xué)習(xí)型的語言,具有較好的并行模型架谎,以及非常適用于編寫 DSL炸宵。

原文:Scala is my next choice

作者:khelll 譯者:[司馬牽牛](http://tsaizb.blog.51cto.com/)

【相關(guān)閱讀】
[Scala取代Java?可能嗎谷扣?熱議仍持續(xù)不斷
](http://developer.51cto.com/art/200907/135770.htm)
[Groovy創(chuàng)始人:Java面臨終結(jié) Scala將取而代之
](http://developer.51cto.com/art/200907/134785.htm)
[Scala如何改變了我的編程風(fēng)格:從命令式到函數(shù)式
](http://developer.51cto.com/art/200906/127825.htm)
[Scala的類型系統(tǒng) 比Java更靈活
](http://developer.51cto.com/art/200906/126710.htm)
[Java程序員土全,你為什么要關(guān)注Scala
](http://developer.51cto.com/art/200905/125526.htm)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市会涎,隨后出現(xiàn)的幾起案子裹匙,更是在濱河造成了極大的恐慌,老刑警劉巖末秃,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件概页,死亡現(xiàn)場離奇詭異,居然都是意外死亡练慕,警方通過查閱死者的電腦和手機(jī)惰匙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铃将,“玉大人项鬼,你說我怎么就攤上這事【⒀郑” “怎么了绘盟?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我龄毡,道長吠卷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任稚虎,我火速辦了婚禮撤嫩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蠢终。我一直安慰自己,他們只是感情好茴她,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布寻拂。 她就那樣靜靜地躺著,像睡著了一般丈牢。 火紅的嫁衣襯著肌膚如雪祭钉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天己沛,我揣著相機(jī)與錄音慌核,去河邊找鬼。 笑死申尼,一個胖子當(dāng)著我的面吹牛垮卓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播师幕,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粟按,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霹粥?” 一聲冷哼從身側(cè)響起灭将,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎后控,沒想到半個月后庙曙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡浩淘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年捌朴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馋袜。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡男旗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欣鳖,到底是詐尸還是另有隱情察皇,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站什荣,受9級特大地震影響矾缓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稻爬,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一嗜闻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桅锄,春花似錦琉雳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辫秧,卻和暖如春束倍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盟戏。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工绪妹, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柿究。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓邮旷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親笛求。 傳聞我的和親對象是個殘疾皇子廊移,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容