Lua學習個人筆記

1.1程序塊:Lua執行的每段代碼,例如一個源代碼文件或者交互模式中輸入的一行代碼,都稱為一個程序塊

1.2注釋:- - or --[[ --]]

1.3全局變量:無需聲明,只需將值賦予一個全局變量就可以創建了。無需刪除,若要刪除直接賦值nil。

1.4解釋器程序
選項參數“-e”可以直接在命令行中輸入代碼。
選項參數“-l”用于加載庫文件。
選項參數“-i”表示在運行完其他命令行參數后進入交互模式
只要定義了一個名為“_PROMPT”的全局變量。解釋器就會用它的值作為交互模式的命令提示符。例如
CXQ-MacBook-Pro:LUA-learn chenxiaoqiang$ lua -i -e "_PROMPT = 'lua>'"Lua 5.3.0 Copyright (C) 1994-2015 Lua.org, PUC-Rio
lua>//提示符

類型與值
Lua動態類型的語言。無類型定義的語法。
總共八種數據類型:nil表示“無效值”
boolean:true or false
number:表示的十實數

string字符串:Lua字符串是不可變的值。不能像C語言一樣直接修改字符串的某個字符,而是應該根據修改要求來創建一個新的字符串。
a = “one string"
b= string.gsub(a, “one”, “anther")
“..”是Lua字符串連續操作符。數字后面記得先空格,不然會默認為小數點
例如:print(10 .. 20)
盡量不要使用這種強制轉換。 而應該使用print(tostring(10)).

table:對象,永遠是“匿名的”,一個持有table的變量與table自身之間沒有固定的關聯性。
lua>a = {}lua>k = "x"lua>a[k] = 100
lua>a[20] = "great"
lua>b=a
print(b[“x”]) —->100 等同于b.x

a = nil
b = nil
Lua中數組通常以1作為索引的起始值

Lua中長度操作符“#“用于返回一個數組或線性表的最后一個索引值(或為其大?。?br> — - 打印所有行

for i=1, #a do
print(a[i])
end
print(a[#a]) - -打印列表a的最后一個值
a[#a] = nil --刪除最后一個值
a[#a+1] = v - -將v添加到列表末尾
user data(自定義類型),function,thread.
print(type(“hello world"))

表達式
table構造式
空構造式{}
days = {“Sunday”,”Monday”} days[1] = “Sunday”….
lua>polyline = {color = "blue", thickness = 2, npoints = 4,
{x=0,y=0},{x=-10,y=0}}
print(polyline[2].x) - - -10
構造式{x = 0, y = 0}相當于{[“x”]=0,[“y”]=0}
構造式{“r”,”g”,”b”}相當于{[1]= “r”,[2]=“g”,[3]=“b"}

語句
賦值:允許多重賦值,即一下子將多個值賦予多個變量
lua>a,b = 20,5*x
多重賦值:左邊大于右邊個數為nil, 反之則舍棄
局部變量:local語句來創建
局部變量只限于在塊中使用。
一個塊block:是一個控制結構的執行體,或者是一個函數的執行體再或者是一個程序塊。
盡可能的使用局部變量是一種良好的編程風格

控制結構:
if then else end or elseif
while 條件 do
end
repeat-until 語句重復執行其循環體直到條件為真時結束。
在Lua中,一個聲明在循環體中得局部變量的作用域包括了條件測試
數字型for : for var = exp1,exp2,exp3 do
end
var從exp1變化到exp2,每次步長為exp3。
如果不想有上限則使用math.huge
泛型for: 循環通過一個迭代器(iterator)函數來遍歷所有值
打印a的所有值
for i,v in ipairs(a) do print(v) end
Lua的基礎庫提供了ipairs,這是一個用于遍歷數組的迭代器函數。
i會被賦予一個索引值,v被賦予一個對應于索引值的數組元素值

函數
多重返回值:Lua允許函數返回多個結果
unpack函數。接受一個數組作為參數,并從下標1開始返回該數組的所有元素

function unpack(t,i)>> i = i or 1>> if t[i] then>> return t[i],unpack(t, i + 1)>> end

end

變長函數

function add(...)
local s = 0
for i,v in ipairs(...) do
s= s + v
end
return s
…表示函數可接受不同數量的實參

function fwrite(fmt, ...)>> return io.write(string.format(fmt, ...))>> end
fwrite("%d%d",4,5)
格式化文本string.format
一個函數在遍歷其變長參數時只需使用表達式{…}。如果變長參數中包含一些故意傳入的nil,那么此時就需要用函數select來訪問變長參數了。調用select的時候必須傳入一個固定參數selector和一系列變長參數。調用selector為數字N,那么select返回它的第n個可變實參;否則,selector只能為字符串”#“,這樣select會返回變長參數的總數

具名實參

深入函數
在Lua中。函數是一種”“第一類值”,它們具有特定的詞法域
第一類值:表示在Lua中函數與其他傳統的類型的值(例如數字和字符串)具有相同的權利。函數可以存儲到變量中無論是全局或者是局部?;騮able中,可以作為實參傳遞給其他函數,還可以作為其他函數的返回值
詞法域:一個函數可以嵌套在另一個函數中,內部的函數可以訪問外部函數中的變量。

函數與所有其他值一樣都是匿名的。即它們都沒有名稱。當討論一個函數名時(例如print),實際上是在討論一個持有某函數的變量。這與其他變量持有各種值是一個道理。

a = {p = print}
a.p("hello")
hello
function foo (x) return 2x end
等同于 foo = function (x) 2
x end
一個函數定義實際就是一條語句。

閉合函數closure

function sortgrade(names,grades) table.sort(names, function(n1,n2)>> return grades[n1] > grades[n2]>> end)

end
grades稱為“非局部的變量”。既不是全局也不是局部。但sort中得匿名函數卻可以訪問
function newCounter()>> local i = 0>> return function()>> i = i + 1>> return i>> end
end
c1 = newCounter()
c2 = newCounter()
一個closure就是一個函數加上該函數所需訪問的所有“非局部的變量”。如果再次調用newCounter,那么它會創建一個新的局部變量i,從而得到一個新的closure.
closure對于回調函數也很有用。

非全局的函數

Lib = {}> Lib.foo = function (x,y) return x+y end
Lib.goo = function (x,y) return xy end
上下實現是相同的
function Lib.foo (x,y) return x+y end
function Lib.goo (x,y) return x
y end
定義遞歸的局部函數時,有特別需要注意的地方。先定義一個局部變量,然后再定義函數本身
local fact
fact = function(n) - - 若是local fact = function(n)會有錯誤,定義未完畢
if n == 0 then return 1
else return n*fact(n-1)
end
end
正確地尾調用
Lua支持“尾調用消除”:尾調用(tail call)就是一種類似于goto的函數調用。當一個函數調用是另一個函數的最后一個動作時,該調用才算是一條“尾調用”。舉例:
function f(x) return g(x) end
也就是說當f調用完g后就再無其他事情可做了。(尾調用不消耗??臻g)
不符合尾調用的一些情況
return g(x) + 1 必須做一次加法
return x or g(x)
return (g(x)) 必須調整為一個返回值
在Lua 中,只有return <func>(<args>)這樣的調用形式才算是一條尾調用

尾調用的一大應用就是編寫“狀態機”。這種程序通常以一個函數來表示一個的狀態,改變狀態就是goto到另一個特定的函數。

迭代器與泛型for
迭代器與closure
迭代器:就是一種可以遍歷一種集合中所有元素的機制。在Lua中通常將迭代器表示為函數,每調用一次函數,即返回集合中的“下一個”元素
一個closure結構通常涉及到兩個函數:closure本身和一個用于創建該closure的工廠函數。
例子:

function values(t)>> local i = 0>> return function () i = i+1; return t[i] end>> end> t = {10,20,30}> iter = values(t)> while true do>> local element = iter()>> if element == nil then break end>> print(element)

end
泛型for
for element in values(t) do>> print(element)
end
i = i + 1>> return i>> end
>> end
> c1 = newCounter()
> c2 = newCounter()
一個closure就是一個函數加上該函數所需訪問的所有“非局部的變量”。如果再次調用newCounter,那么它會創建一個新的局部變量i,從而得到一個新的closure.
closure對于回調函數也很有用。

非全局的函數
> Lib = {}> Lib.foo = function (x,y) return x+y end
> Lib.goo = function (x,y) return xy end
上下實現是相同的
> function Lib.foo (x,y) return x+y end
> function Lib.goo (x,y) return x
y end
定義遞歸的局部函數時,有特別需要注意的地方。先定義一個局部變量,然后再定義函數本身
local fact
fact = function(n) - - 若是local fact = function(n)會有錯誤,定義未完畢
if n == 0 then return 1
else return n*fact(n-1)
end
end
正確地尾調用
Lua支持“尾調用消除”:尾調用(tail call)就是一種類似于goto的函數調用。當一個函數調用是另一個函數的最后一個動作時,該調用才算是一條“尾調用”。舉例:
function f(x) return g(x) end
也就是說當f調用完g后就再無其他事情可做了。(尾調用不消耗??臻g)
不符合尾調用的一些情況
return g(x) + 1 必須做一次加法
return x or g(x)
return (g(x)) 必須調整為一個返回值
在Lua 中,只有return <func>(<args>)這樣的調用形式才算是一條尾調用

尾調用的一大應用就是編寫“狀態機”。這種程序通常以一個函數來表示一個的狀態,改變狀態就是goto到另一個特定的函數。

迭代器與泛型for
迭代器與closure
迭代器:就是一種可以遍歷一種集合中所有元素的機制。在Lua中通常將迭代器表示為函數,每調用一次函數,即返回集合中的“下一個”元素
一個closure結構通常涉及到兩個函數:closure本身和一個用于創建該closure的工廠函數。
例子:
> function values(t)>> local i = 0>> return function () i = i+1; return t[i] end>> end> t = {10,20,30}> iter = values(t)> while true do>> local element = iter()>> if element == nil then break end>> print(element)
>> end
泛型for
> for element in values(t) do>> print(element)
>> end
泛型for的語法:for <var-list> in <exp-list> do
<body>
end
其中<var-list>是一個或多個變量名的列表,以逗號分隔;<exp-list>是一個或多個表達式的列表,同樣以逗號分隔。通常表達式列表只有一個元素,即對迭代器工廠的調用。例如
for k,v in pairs(t) do print(k,v) end
變量列表的第一元素稱為“控制變量”。在循環過程中該值絕不會是nil
for做的第一件事就是對in后面的表達式求值。這些表達式應該返回3個值供for保存:
迭代器函數、恒定狀態和控制變量 的初值。這里類似于多重賦值,即只有最后一個表達式才會產生多個結果,并且只會保留前3個值,多余的值會被丟棄;而不足的話將以nil補足。

無狀態的迭代器
就是一種自身不保存任何狀態的迭代器。因此,我們可以在多個循環中使用同一個無狀態的迭代器,避免創建新的closure開銷。
在每次迭代中,for循環都會用恒定狀態和控制變量來調用迭代器函數,一個無狀態的迭代器可以根據這兩個值來為下次迭代生成一個元素。例如ipairs。

具有復雜狀態的迭代器

local iterator> function allwords()>> local state = {line = io.read(), pos = 1}>> return iterator, state>> end> function iterator(state)>> while state.line do>> local s,e = string.find(state.line, "%w+", state.pos)>> if s then>> state.pos = e + 1>> return string.sub(state.line, s, e)>> else>> state.line = io.read()>> state.pos = 1>> end>> end>> return nil

end

協同程序
概念:協同程序與線程差不多,也就是一條執行序列,擁有自己獨立的棧、局部變量和指令指針,同時又與其他系統程序共享全局變量和其他大部分的東西。
一個具有多個協同程序的程序在任意時刻只能運行一個協同程序。并且正在運行的協同程序只會在其顯式地要求掛起時,它的執行才會暫停。

1.基礎知識:
協同程序的函數放置在一個名為“coroutine”的table中。
四個狀態:掛起、運行、死亡、正常。
coroutine.create() coroutine.resume() coroutine.status() coroutine.yield()
協同程序的真正強大之處在于函數yield的使用上,該函數可以讓一個運行中的協同程序掛起,而之后可以再恢復它的運行。
Lua>co = coroutine.create(function ()>> for i=1,10 do>> print("co",i)>> coroutine.yield()>> end

end)
在resume,并沒有對應的yield在等待它,因此所有傳遞給resume的額外參數都將視為協同程序的主函數的參數。
Lua>co = coroutine.create(function (a,b,c) print("co",a,b,c) end)
Lua>return coroutine.resume(co,1,2,3)
在resume調用返回的內容中,第一個值為true則表示沒錯,而后面所有的值都是對yield傳入的參數:
Lua>co = coroutine.create(function (a,b)>> coroutine.yield(a+b,a-b)>> end)
Lua>coroutine.resume(co,10,9)
與此對應的是,yield的返回的額外值就是對應resume傳入的參數:
print("co",coroutine.yield())
end)
return iterator, state>> end> function iterator(state)>> while state.line do>> local s,e = string.find(state.line, "%w+", state.pos)>> if s then>> state.pos = e + 1>> return string.sub(state.line, s, e)>> else>> state.line = io.read()>> state.pos = 1>> end>> end>> return nil
>> end

協同程序
概念:協同程序與線程差不多,也就是一條執行序列,擁有自己獨立的棧、局部變量和指令指針,同時又與其他系統程序共享全局變量和其他大部分的東西。
一個具有多個協同程序的程序在任意時刻只能運行一個協同程序。并且正在運行的協同程序只會在其顯式地要求掛起時,它的執行才會暫停。

1.基礎知識:
協同程序的函數放置在一個名為“coroutine”的table中。
四個狀態:掛起、運行、死亡、正常。
coroutine.create() coroutine.resume() coroutine.status() coroutine.yield()
協同程序的真正強大之處在于函數yield的使用上,該函數可以讓一個運行中的協同程序掛起,而之后可以再恢復它的運行。
Lua>co = coroutine.create(function ()>> for i=1,10 do>> print("co",i)>> coroutine.yield()>> end
>> end)
在resume,并沒有對應的yield在等待它,因此所有傳遞給resume的額外參數都將視為協同程序的主函數的參數。
Lua>co = coroutine.create(function (a,b,c) print("co",a,b,c) end)
Lua>return coroutine.resume(co,1,2,3)
在resume調用返回的內容中,第一個值為true則表示沒錯,而后面所有的值都是對yield傳入的參數:
Lua>co = coroutine.create(function (a,b)>> coroutine.yield(a+b,a-b)>> end)
Lua>coroutine.resume(co,10,9)
與此對應的是,yield的返回的額外值就是對應resume傳入的參數:
>> print("co",coroutine.yield())
>> end)
Lua>coroutine.resume(co)trueLua>return coroutine.resume(co,1,2)
co 1 2
最后,當一個協同程序結束時,它的主函數所返回的值都將作為對應resume的返回值。
Lua>co = coroutine.create(function()>> return 6,7>> end)
Lua>print(coroutine.resume(co))
true 6 7

  1. 管道(pipe)與過濾器(filter)
    協同程序經典案例“生產者-消費者”
    Lua>function receive(prod)>> local status, value = coroutine.resume(prod)>> return value>> endLua>function send(x)>> coroutine.yield(x)>> endLua>function producer()>> return coroutine.create(function ()>> while true do>> local x = io.read()>> send(x)>> end>> end)>> endLua>function filter(prod)>> return coroutine.create(function()>> for line = 1, math.huge do>> local x = receive(prod)>> x = string.format(%5d %s",line,x)stdin:5: unexpected symbol near '%'
    Lua>function filter(prod)
    return coroutine.create(function()
    for line = 1, math.huge do
    local x = receive(prod)
    x = string.format("%5d %s",line,x)
  send(x)>>     end>>  end)>> endLua>function consumer (prod)>>    while true do>>      local x = receive(prod)>>      io.write(x, "\n")>>    end>> endLua>p = producer()Lua>f = filter(p)

Lua>consumer(f)

以協同程序實現迭代器
非搶占式的多線程

數據結構
1.數組
a = {} 新建
for i=1, 1000 do a[i] = 0
end

mt = {}

for i=1,N do mt[i] = {} --創建一個新行 for j=1,M do mt[i][j] = 0 end
Lua中table是一種對象,因此在創建矩陣時,必須顯示地創建每一行。

元表(metatable)與元方法(meatmethod)

通常,Lua中得每個值都有一套預定義的操作集合。例如,數字相加,連接字符串。但是無法相加兩個table,無法對函數比較,也無法調用一個字符串。
可以通過元表來修改一個值得行為,使其在面對一個非預定義的操作時執行一個指定的操作。
例如定義如何相加table的表達式。
Lua試圖相加兩個table時,它會先檢查兩者之一是否有元表,然后檢查該元表中是否有一個叫_add的字段。如果Lua找到了該字段,就調用該字段對應的值。這個值也就是所謂的“元方法”,它應該是一個函數。
Lua中得每個值都有一個元表。Lua在創建新的table時不會創建元表:
t = {} print(getmetatable(t)) - - nil

使用setmetatable來設置或修改任何table的元表:

t = {}
t1 = {}
setmetatable(t, t1)
assert(getmetatable(t) == t1)

任何table都可以作為任何值的元表,而一組相關的table也可以共享一個通用的元表,此元表描述了它們的共同行為,一個table甚至可以作為它自己的元表,用于描述其特有的行為。
在Lua中只能設置table的元表。其他需要通過C代碼來完成。

算術類的元方法
Set = {}
local mt = {}
function Set.new(l)
local set = {}
setmetatable(set, mt)
for _,v in ipairs(l) do
set[v] = true
end
return set
end

function Set.union(a,b)
local res = Set.new{}
for k in pairs(a) do
res[k] = true
end
for k in pairs(b) do
res[k] = true
end
return res
end

function Set.intersection (a,b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end

function Set.tostring(set)
local l = {}
for e in pairs(set) do
l[#l + 1] = e
end
return "{" .. table.concat(l, ", ") .. "}"
end
function Set.print(s)
print(Set.tostring(s))
end

s1 = Set.new{10,20,30,40}
s2 = Set.new{30,1}

mt.__add = Set.union
s3 = s1 + s2
Set.print(s3)
mt.__mul = Set.intersection
Set.print((s1+s2)*s1)
如果想要清楚得到錯誤信息,則必須在實際操作前顯示地檢查操作數的類型
關系類的元方法
table訪問的元方法
有兩種可以改變table的行為:查詢table及修改table中不存在的字段
_ _index元方法:如果有此方法當訪問查詢不到的時候會調用此方法(繼承)table的更新
元方法可以是函數也可以是另一個table
_ newindex:用于table的更新。功能相似
兩者的組合可以實現Lua的一些強大的功能:只讀的table,默認值的table和面向對象編程
1.默認值的table
function setDefault (t,d)
local mt = {
_index = function () return d end}
setmetatable(t,mt)
end

環境
Lua將其所有的全局變量保存在一個常規的table中,這個table稱為“環境(environment)”
優點:其一,不需要再為全局變量創造一種新的數據結構,因此簡化了Lua的內部實習。另外一個優點是,可以像其他table一樣操作這個table。
為了便于實時這種操作,Lua將環境table自身保存在一個全局變量_G中。以下代碼打印當前環境所有全局變量的名稱:
for n in pairs(_G) do print(n) end
全局變量聲明:

value = _G["varname"]> valuex> _G["test"] = value
test
非全局的環境
setfenv(1,{})將當前環境改為一個新的空table
1表示當前函數,2表示調用當前函數的函數
模塊與包
1.require函數
即使知道某些用到的模塊可能已經加載了,但只要用到require就是一個良好的編程習慣。
2.編寫模塊的基本方法
最簡單的方法:創建一個table
3.使用環境
創建模塊的基本方法的缺陷在于,它要求程序員投入一些額外的關注。當訪問同一模塊中的其他公共實體時,必須限定其名稱。并且,只要一個函數的狀態從私有變為公有(反之也可),就必須修改調用。
函數環境可以解決上述創建模塊時遇到的問題

面向對象編程
Lua的table是一種對象,首先:table與對象一樣可以擁有狀態,其次,table也與對象一樣擁有一個獨立于其值得標識(一個self)。最后table與對象一樣具有獨立于創建者和創建地的生命周期。
self的使用

Account = {balance = 0}> function Account.withdraw(v)>> Account.balance = Account.balance - v>> end
Account.withdraw(100.0)
Account = nil
a.withdraw(0) --錯誤
通過一個額外的參數self or this修改。
Account = {balance = 0}> function Account.withdraw(self,v)>> self.balance = self.balance - v>> return self.balance>> end
a = Account
return a.withdraw(a,100)
在Lua中。只需要使用冒號,就可以隱藏self參數
function Account:withdraw(v)>> self.balance = self.balance - v

end
a = Account
Account = nil
return a:withdraw(100)
1.類:
在Lua中實現原型很簡單,使用繼承即可。更準確地說,如果有兩個對象a和b,要讓b作為a的一個原型,只需輸入下面語句
setmetable(a,__index = b)
在此之后,a就會在b中查找所有它沒有的操作,若將b稱為是對象a的類,只不過是術語上的一個變化而已。
Account = {balance = 0}
function Account:new(o)
o = o or {} setmetatable(o,self) self.__index = self
return o
end
當調用Account:new的時候,self就等于Account
2.繼承
由于類也是對象,它們也可以從其他類獲得方法。這種行為就是一種繼承,可以很容易地在Lua中。
Account = {balance = 0}
function Account:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end

function Account:withdraw(v)
if self.balance < v then print("insufficient funds") end
self.balance = self.balance - v
end
function Account:deposit(v)
self.balance = self.balance + v
end
--派生子類使得賬戶可以透支
SpecialAccount = Account:new()
s = SpecialAccount:new{limit = 1000.0}
function SpecialAccount:withdraw(v)
if v - self.balance >= self:getLimit() then
print("insufficient funds")
end
self.balance = self.balance - v
end

function SpecialAccount:getLimit()
return self.limit or 0
end

test = SpecialAccount:new()
test:withdraw(500)
print(test.balance)

3.多重繼承

弱引用table
三種方式:弱引用table,弱引用key,弱引用兩者
一個table的弱引用類型是通過其元表中得—mode字段來決定的。這個字段的值應為一個字符串,如果這個字符串包含字母’k’,那么這個table的key是弱引用;如果這個字符串包含字母’v’,那么這個table是value的弱引用,

a = {}b= {__mode = "k"}setmetatable(a,b) --'a'為key的弱引用key = {}a[key] = 1key = {}a[key] = 2collectgarbage()for k,v in pairs(a) do print(v)
end
備忘錄
local results = {}
setmetateble(results,{__mode = "v"})function createRGB(r,g,b) local key = r .. "-" .. g "-" .. b local color = results(key) if color == nil then color = {red = r, green = g, blue = b} results[key] = color end return color
end

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

推薦閱讀更多精彩內容

  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,478評論 0 17
  • 你我皆普通 無太多崢嶸 生命數十載 一如穿堂風 從最初 天馬行空 到后來 萬物皆空 成長的歸途 每邁出一步 都伴隨...
    敏敏L_7495閱讀 129評論 0 0
  • 路還長,天總會亮! 2016年12月2日,我又多了一個身份——母親。 這一個月過的云里霧里,不算安穩。 在新年到來...
    RabbitLiRL閱讀 453評論 0 3
  • 2017年7月14日晚,王女士到順義公安分局后沙峪派出所報案,稱被男友“周某”騙取錢財共計人民幣90余萬元。但經民...
    丁舒士閱讀 229評論 0 0
  • SQL注入 疑問:SQL語句拼接變量 //直接把獲取的$id代入(有問題)$sql...
    allin2閱讀 4,676評論 1 4