在Linux系統(tǒng)上搭建Swift開發(fā)調(diào)試環(huán)境

Swift與Linux

自2015年Swift宣布開源并支持Linux后,一晃已超過5年。在最初幾年間盡管Swift發(fā)展迅速,但并未被Linux社區(qū)廣泛接受。造成這種局面的原因較多,其中既有語言穩(wěn)定性方面的問題,同時又有對Linux的支持不完善、缺乏具有吸引力的基礎(chǔ)庫和第三方庫、熱點項目不足等多方面原因。

最近兩年,上述問題均得到顯著改善。

  • 從Swift5開始Swift團隊宣布ABI穩(wěn)定了。自此,Swift為應(yīng)用程序提供了二進制兼容性,有了ABI穩(wěn)定性作為基礎(chǔ),Swift對其他平臺的支持速度和力度將大大提高
  • 2020年Swift團隊推出了5.3版本,除了“重要的質(zhì)量提升和性能增強”之外,Swift5.3的一個關(guān)鍵特性是正式支持Linux和Window平臺。事實上,這也是Swift的發(fā)布流程首次為三個不同的平臺分別設(shè)立了發(fā)布負責(zé)人。作為承諾將Swift引入Linux的第一份成果,Swift團隊宣布新的Swift版本可用于一眾Linux發(fā)行版上。
  • 出現(xiàn)了大量優(yōu)秀的官方和第三方的跨平臺庫。僅Apple公司,最近幾年來已經(jīng)為Swift社區(qū)貢獻了大量的Swift代碼,并保持著非常高的提交頻率。
  • Swift在服務(wù)器端及深度學(xué)習(xí)領(lǐng)域取得了不錯的應(yīng)用成果。

Swift已經(jīng)準備在Linux有更多的表現(xiàn)。

寫本文的原因

前些日子寫了篇用Publish創(chuàng)建博客(一)——入門(一個用Swift編寫的優(yōu)秀的靜態(tài)網(wǎng)站生成器)的介紹,期間有網(wǎng)友問我是否可以在Linux上使用,我回答不成問題。但轉(zhuǎn)過頭來思考,雖然Publish完美地支持Linux,但開發(fā)者能否像在mac上一樣方便的進行開發(fā)調(diào)試呢?

之前使用Vapor的時候,曾通過Docker在Ubuntu上安裝過Swift,不過代碼是在mac上調(diào)試的。我也十分好奇,在2021年Swift到底在Linux下的開發(fā)環(huán)境如何?

本文的目標是在Linux上搭建一個可供生產(chǎn)標準的Swift開發(fā)調(diào)試環(huán)境。使用者將獲得一個支持代碼高亮、自動補全、定義跳轉(zhuǎn)、斷點調(diào)試、代碼美化、代碼靜態(tài)掃描、跨操作系統(tǒng)平臺配置的綜合開發(fā)體驗。

準備

由于每個人使用的Linux發(fā)行版本不同,因此在安裝過程中,如遇到缺少必要依賴的情況,請自行按系統(tǒng)提示安裝所需的依賴庫即可。

本文在描述每一步該如何做的同時,還會做出必要的解釋。即使你使用的是其他的Linux發(fā)行版,或者不同的編輯器,甚至在Swift或其他工具發(fā)生了重大的升級后,仍可按照下面安裝思路進行環(huán)境搭建。

本文搭建的起點是建立在已經(jīng)安裝了Visual Studio Code 1.53.0的Ubuntu 20.04LTS(最小化安裝)系統(tǒng)上的。選擇安裝的Swift Toolchain為5.3.3。

對于Ubuntu 20.04,需安裝python2.7npm以完成下面其他操作。

$ sudo apt install libpython2.7 libpython2.7-dev libz3-4 npm 

Swift Toolchain

工具鏈選擇

盡管你可以直接下載Swift Toolchain的源碼自己編譯,但目前最推薦的方式還是使用官方提供的已編譯好的下載包進行安裝。swift.org上提供了Ubuntu 16.04、Ubuntu 18.04、Ubuntu 20.04、CentOS 7、CentOS 8、Amazon Linux 2的下載包。其他的發(fā)行版本也多有自己的官方支持,比如Fodor、Red Hat Enterprise Linux8、Raspbian OSi等

Swift在5.3版本后開始正式支持Linux平臺,所以本文選擇在Ubuntu 20.04上安裝Swift 5.3.3 Release。

安裝

swift.org上查找對應(yīng)發(fā)行版的Swift Toolchain下載地址

image-20210214092353715
$cd ~
$wget https://swift.org/builds/swift-5.3.3-release/ubuntu2004/swift-5.3.3-RELEASE/swift-5.3.3-RELEASE-ubuntu20.04.tar.gz

解壓文件

$tar -xzf swift-5.3.3-RELEASE-ubuntu20.04.tar.gz 

swift工具鏈將被解壓在 ~/swift-5.3.3-RELEASE-ubuntu20.04目錄中,將該目錄移動到你習(xí)慣的路徑,比如:

$sudo mv swift-5.3.3-RELEASE-ubuntu20.04 /usr/share/swift

請記住移動后的路徑/usr/share/swift,該路徑將在下面的配置中被多次使用到。

將swift bin的路徑添加到環(huán)境中

$echo "export PATH=/usr/share/swift/usr/bin:$PATH" >> ~/.bash
$source .bash

至此,Swift已經(jīng)在當(dāng)前系統(tǒng)上安裝好了

$swift --version
Swift version 5.3.3 (swift-5.3.3-RELEASE)
Target: x86_64-unknown-linux-gnu

運行第一段代碼

創(chuàng)建hello.swift,內(nèi)容為

#!/usr/bin/env swift
print("My first swift code")
$cd ~
$swift hello.swift
My first swift code

或者可以將swift代碼當(dāng)做script來執(zhí)行

$chmod +755 hello.swift
$./hellow.swift
My first swift code

創(chuàng)建第一個Swift項目

Swift Package Manager (SPM) 是蘋果推出的用于創(chuàng)建使用swift的庫和可執(zhí)行程序的工具。目前它已經(jīng)是Swift Toolchain的一部分了。

創(chuàng)建可執(zhí)行程序項目

$cd ~
$mdkir MyProject
$cd MyProject
$swift package init --type executable
Creating executable package: MyProject
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/MyProject/main.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/MyProjectTests/
Creating Tests/MyProjectTests/MyProjectTests.swift
Creating Tests/MyProjectTests/XCTestManifests.swift

編譯并運行該項目

~/MyProject$swift run
[4/4] Linking MyProject
Hello, world!

該項目在下面的配置中還將使用到。也可以直接使用vscode打開項目文件

~/MyProject$code .
image-20210214144908318

vscode對于Swift已經(jīng)內(nèi)置支持了代碼高亮。

SourceKit-LSP

什么是LSP

LSP的全程是Language Sever Protocol,是微軟提出的一項標準化協(xié)議,旨在統(tǒng)一開發(fā)工具與Lanuguage Server之間的通信。LSP為支持的語言提供了一套通用的功能集,包括:語法高亮、自動補全、定義跳轉(zhuǎn)、查找引用等等。蘋果公司從2018年開始為Swift社區(qū)提供了LSP的代碼及支持。目前LSP已經(jīng)被集成到了Swift的工具鏈中。

安裝

盡管Swift ToolChain中已經(jīng)集成了LSP,但是我們還是需要為vscode安裝對應(yīng)的插件并進行配置,才能在vscode中使用Swift的LSP功能。

由于Swift LSP插件沒有被放置在vscode的插件市場中,我們還是需要從蘋果的LSP Github站點上下載

$git clone https://github.com/apple/sourcekit-lsp.git

下載的文件包含全部LSP的代碼和插件代碼,我們只需安裝插件代碼。

$cd sourcekit-lsp/Editors/vscode/
$npm run createDevPackage 
image-20210214151421778

編譯成功的插件被放置在 ~/sourcekit-lsp/Editors/vscode/out目錄中。

配置vscode

通過命令行將插件安裝到vscode上

$cd ~/sourcekit-lsp/Editors/vscode/out
$code --install-extension sourcekit-lsp-vscode-dev.vsix

或者在vscode中選擇該插件進行安裝

image-20210214151923560

配置Settings

image-20210214154131957

由于lsp已經(jīng)集成到了swift toolchain中,因此在我們安裝toolchain時,它已經(jīng)被安裝到了/usr/share/swift/usr/bin的目錄中,并且該目錄也已經(jīng)設(shè)置在環(huán)境的PATH中,因此通常無需指定絕對路徑,vscode便可以使用swift的lsp功能。如果你自己單獨下載了新版本的lsp,可以在settings.json中設(shè)置對應(yīng)的路徑。

"sourcekit-lsp.serverPath": "/usr/share/swift/usr/bin/sourcekit-lsp"

安裝完成后,vscode便可支持代碼自動補全、定義跳轉(zhuǎn)等功能。

swift_in_linux_lsp_demo

LLDB

什么是LLDB

LLDB調(diào)試器是LLVM項目的調(diào)試器組件。它構(gòu)建為一組可重用的組件,這些組件廣泛使用LLVM中的現(xiàn)有庫,例如Clang表達式解析器和LLVM反匯編程序。通過LLDB,讓vscode擁有了對Swift代碼進行調(diào)試的能力。

安裝

由于Swift Toolchain當(dāng)前已經(jīng)集成了LLDB,因此我們無需對其進行安裝,只需要安裝vscode的lldb插件即可。

在vscode的插件市場中,安裝CodeLLDB

image-20210214160313240

settings.json中指定lldb的位置

"lldb.library": "/usr/share/swift/usr/lib/liblldb.so"

也可以在settings UI中設(shè)定

image-20210214170242254

調(diào)試配置文件

在vscode中用lldb對項目進行調(diào)試,需要在項目的.vscode目錄中針對每個項目分別創(chuàng)建調(diào)試配置文件launch.jsontasks.json。

launch.json是vscode用于調(diào)試的配置文件,比如指定調(diào)試語言環(huán)境,指定調(diào)試類型等等。其作用和XCode中的target類似。在swift項目中,我們通常會設(shè)置兩個configuration,一個用于調(diào)試程序,一個用于進行Unit testing。

$cd MyProject
$code .

在第一次點擊左側(cè)的run按鈕時,vscode會提示創(chuàng)建launch.json文件,我們也可以自己手動在.vscode目錄中創(chuàng)建該文件。

image-20210214172254927

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb", 
            "request": "launch",
            "name": "Debug",
            "program": "${workspaceFolder}/.build/debug/MyProject",
            "args": [],
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "swift-build"
        },
        {
            "type": "lldb",
            "request": "launch",
            "name": "unit testing on Linux",
            "program": "./.build/debug/MyProjectPackageTests.xctest",
            "preLaunchTask": "swift-build-tests"
        }
    ]
}
  • type

    用于此啟動配置的調(diào)試器的類型,swift調(diào)試需設(shè)置成lldb

  • request

    此啟動配置的請求類型,swift調(diào)試需設(shè)置成launch,

  • name

    在調(diào)試啟動配置下拉列表中的顯示名稱

  • program

    可執(zhí)行文件的位置。使用swift build編譯后(不加realase參數(shù))的執(zhí)行文件被放置在項目目錄${workspaceFolder}/.build/debug/下,文件名通常為項目名稱(本例為MyProject);swift build -c release編譯后的執(zhí)行文件放置在${workspaceFolder}/.build/release/下,文件名為項目名稱(本例為MyProject);unit testing的可執(zhí)行文件放置在${workspaceFolder}/.build/debug/,文件名通常為項目名稱PackageTests.xctest(本例為MyProjectPackageTests.xctest)。請根據(jù)每個項目的名稱、配置設(shè)定該項。

  • args

    傳遞給程序的參數(shù)。比如你的項目支持啟動參數(shù)設(shè)定MyProject name hello,則args["name","hello"]

  • cwd

    當(dāng)前工作目錄,用于查找依賴關(guān)系和其他文件

  • preLaunchTask

    要在調(diào)試會話開始之前啟動的任務(wù),每個任務(wù)都需要在tasks.json中有對應(yīng)的設(shè)定。比如本例中,swift-build對應(yīng)著tasks.json中的label:swift-build的task。對于swift項目,在調(diào)試前最常作的工作便是編譯。

tasks.json

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "swift-build",
            "type": "shell",
            "command":"swift build"
        },
        {
            "label": "swift-build-tests",
            "type": "process",
            "command": "swift",
            "args": [
                "build",
                "--build-tests"
            ]
        }
    ]
}
  • lable

    launch.json中的preLaunchTask對應(yīng)

  • type

    shellprocess,為了更好的演示,本例中兩種形式都采用了。

  • command

    如果typeprocesscommnad只能為需要執(zhí)行命令的可執(zhí)行文件名稱(不可帶參數(shù)),在本例中為swift,如果typeshell則可以在command中直接寫上需要調(diào)用的參數(shù),比如swift build

  • args

    對于typeprocess的情況,需要調(diào)用的參數(shù)在此填寫。在本例中,swift-build-tests也可以寫成

"label": "swift-build-tests",
"type": "shell",
"command": "swift build --build-tests"

launch.jsontasks.json還有很多其他的選項,更多的用法請參閱vscode手冊以及SPM手冊。

現(xiàn)在我們就可以開始對Swift項目進行調(diào)試了

第一次調(diào)試

$cd MyProject
$code .

隨便給main.swift添加點內(nèi)容,比如:

import Foundation
let a = 100
print("Hello, world!\(Int.random(in: 0...100))")
print("a:\(a)")
swift-in-linux-lldb-demo

SwiftFormat

為什么要對代碼Foramt

許多項目都有固定的代碼風(fēng)格,統(tǒng)一的代碼規(guī)范不僅有助于項目的迭代和維護,同時也讓代碼更加美觀和易讀。但并不是每個程序員都能夠掌握并熟練使用項目風(fēng)格約定。通過使用自動化工具完成上述工作是讓人十分愜意的事情。

Swift社區(qū)中有多個Format項目,目前最活躍的有nicklockwoodswiftformatAppleswift-format。本例中,我們選擇安裝nicklockwoodswiftformat。兩者的安裝方法類似,相對來說swiftformat支持的規(guī)則更多,另外同Swift 的版本也不像swift-foramt那樣需要嚴格綁定。

安裝命令行工具

$cd ~
$git clone https://github.com/nicklockwood/SwiftFormat.git
$cd SwiftFormat
$swift build -c release
$sudo cp ~/SwiftFormat/.build/release/swiftformat /usr/local/bin
$swiftformat --version
0.47.11

安裝vscode插件

swiftformat、swift-format以及swiftlint的vscode插件都是由Valentin Kabel開發(fā)的,他同時還管理、開發(fā)了其他及個vscode下的swift插件,為在vscode上更好的使用swift作出了不小的貢獻。

在插件商店選擇swiftformat對應(yīng)的插件(注意不要選錯)。

image-20210214211153478

settings.json中添加

"swiftformat.path": "/usr/local/bin/swiftformat",
"swiftformat.configSearchPaths": [
        "./swiftformat",
        "~/.swiftformat"
        ]

swiftformat將從Swiftformat.configSearchPaths設(shè)定的路徑中嘗試查找用戶自己創(chuàng)建的配置文件(.swiftformat),上面的配置為,如果當(dāng)前目錄沒有,則從用戶根目錄上查找。如果都沒有則使用默認配置和規(guī)則。

swift-in-linux-format-demo

swiftformat目前包含50多個規(guī)則,它的文檔做的很好,可以在Rules.md中找到最新的規(guī)則列表及演示。需要注意的是,vscode目前無法正確的響應(yīng)swiftformat自定義配置中的--indent,需要在vscode中對indent做單獨的設(shè)定(我目前采用的是通過EditorConfig for VS Code做統(tǒng)一設(shè)置)。另外,如果通過swift.options:["--config","~/rules/.swiftformat"]指定的規(guī)則文件的優(yōu)先級高于swiftformat.path中的規(guī)則文件。

SwiftLint

讓代碼更規(guī)范

在計算機科學(xué)中,lint是一種工具程序的名稱,它用來標記源代碼中,某些可疑的、不具結(jié)構(gòu)性的段落。它是一種靜態(tài)程序分析工具,最早適用于C語言,在UNIX平臺上開發(fā)出來。后來它成為通用術(shù)語,可用于描述在任何一種計算機程序語言中,用來標記源代碼中有疑義段落的工具。swift社區(qū)中,被使用的最廣泛的就是realm開發(fā)的SwiftLint。

其實,上面的swiftformat、swift-format都具有l(wèi)int的功能,并且和swiftlint在很多地方的規(guī)則都類似(都基于Github's Swift Style Guide),但各自的特點還是略有不同。

swiftformat更多的表現(xiàn)在對代碼的自動修改上,而swiftlint由于直接hook了Clang和Sourcekit,因此提供了swiftformat所不具備的,代碼錄入階段的實時驗證和提示功能(通常并不使用它的autocorrect)。

安裝命令行工具

$git clone https://github.com/realm/SwiftLint.git
$cd SwiftLint
$swift build -c release
$sudo cp ~/SwiftLint/.build/release/swiftlint /usr/local/bin
$swiftlint --version
0.42.0

安裝vscode插件

在vscode插件市場中安裝swiftlint插件

image-20210215073043096

settings.json中添加

"swiftlint.path": "/usr/local/bin/swiftlint",
"swiftlint.toolchainPath": "/usr/share/swift/usr/bin",
"swiftlint.configSearchPaths": [
        "./.swiftlint.yml",
        "~/.swiftlint.yml"
    ]

configSearchPath的設(shè)置同swiftformat類似,如果不需要自定義配置,則無需填寫。

swift-in-linux-lint-demo

跨平臺配置

我們已經(jīng)在Ubuntu 20.04上構(gòu)建了一個較完整的Swift開發(fā)環(huán)境。

settings

如果你也像我一樣使用了vscode的setting同步功能,那么在其他的平臺(比如mac),上述的settings.json將無法正常使用。

為了讓我們構(gòu)建的開發(fā)環(huán)境適應(yīng)多平臺,需要啟用配置的多平臺支持,并且針對不同平臺分別設(shè)定。

安裝platform-settins插件

image-20210215091440441

修改settings.json

當(dāng)前為:

{
    "sourcekit-lsp.serverPath": "/usr/share/swift/usr/bin/sourcekit-lsp",
    "lldb.library": "/usr/share/swift/usr/lib/liblldb.so",
    "swiftformat.path": "/usr/local/bin/swiftformat",
    "swiftformat.configSearchPaths": [
        "./swiftformat",
        "~/.swiftformat"
    ],
    "swiftlint.path": "/usr/local/bin/swiftlint",
    "swiftlint.toolchainPath": "/usr/share/swift/usr/bin",
    "swiftlint.configSearchPaths": [
        "./.swiftlint.yml",
        "~/.swiftlint.yml"
    ]
}

修改為:

{
    "platformSettings.autoLoad": true,
    "platformSettings.platforms": {
        "linux":{
            "sourcekit-lsp.serverPath": "/usr/share/swift/usr/bin/sourcekit-lsp",
            "lldb.library": "/usr/share/swift/usr/lib/liblldb.so",
            "swiftformat.path": "/usr/local/bin/swiftformat",
            "swiftlint.path": "/usr/local/bin/swiftlint",
            "swiftlint.toolchainPath": "/usr/share/swift/usr/bin",
        },
        "Mac":{
            "sourcekit-lsp.serverPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp",
            "lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB",
            "swiftformat.path": "/usr/local/bin/swiftformat", //homebrew目前也恰巧安裝在此
            "swiftlint.path": "/usr/local/bin/swiftlint", //指向工具的實際路徑
            "swiftlint.toolchainPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin",
        }
    
    },
    "swiftformat.configSearchPaths": [
        "./swiftformat",
        "~/.swiftformat"
    ],
    "swiftlint.configSearchPaths": [
        "./.swiftlint.yml",
        "~/.swiftlint.yml"
    ]
}

launch.json

在mac平臺下,unit testing的調(diào)用方式也和linux下不同,因此需要在launch.json中添加一個configuration,由于使用同一個preLauchchTask,因此tasks.json不用改動。

       {
            "type": "lldb",
            "request": "launch",
            "name": "Debug tests on macOS",
            "program": "/Applications/Xcode.app/Contents/Developer/usr/bin/xctest", //For example /Applications/Xcode.app/Contents/Developer/usr/bin/xctest
            "args": [
                "${workspaceFolder}/.build/debug/MyProjectPackageTests.xctest"
            ],
            "preLaunchTask": "swift-build-tests"
        },
image-20210215092656451

在不同的平臺上,選擇對應(yīng)的target即可。

結(jié)語

希望本文能夠幫助更多的朋友在Linux上使用Swift進行開發(fā)。

我的個人博客肘子的Swift記事本中會有更多關(guān)于Swift、SwiftUI、CoreData的內(nèi)容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,960評論 2 373