哇! Perl 6!!

前言

Slides 地址
视频地址

答案地址

注意 Unicode

Perl 6 允许你使用 Unicode 的项和操作符。
这些 Unicode 都有对应的只使用 ASCII 字符的 Texas 变体, 如果你更喜欢使用它们, 到 http://docs.perl6.org/language/unicode_texas 找到它们。

惰性列表和它们的使用

img

惰性列表

我们来做点儿疯狂的事情吧...例如创建一个无限列表(INIFINITE LIST)!

my @to-infinity-and-beyond = 0, 2 ... ∞;
say @to-infinity-and-beyond[1008]; # 2016

来点更有用的东西: 处理大文件

for '/tmp/4GB-file.txt'.IO.words {
    .say;
    last if ++$ == 3;
}
say "Code took {now - INIT now} seconds to run";

# OUTPUT:
# foo
# bar
# ber
# Code took 0.01111143 seconds to run
.say for '/tmp/4GB-file.txt'.IO.words[0..2];
say "Code took {now - INIT now} seconds to run";

# OUTPUT:
# foo
# bar
# ber
# Code took 0.01111143 seconds to run

塑造你自己的 Subsets, 自定义操作符, Muti-dispatch

img

Subsets

类型的 subset 使你可以约束它能接收的值:

subset BigPrime of Int where { $_ > 10_000 and .is-prime }

sub MAIN ( BigPrime $num ) {
    say "That's a nice-looking prime number you got there!";
}
$ perl6 test.p6 3
Usage:
  test.p6 <num>
$ perl6 test.p6 31337
That's a nice-looking prime number you got there!
$ perl6 test.p6 100000
Usage:
  test.p6 <num>

Multi-Dispatch

多个同名的 subs 或 方法, 但是拥有不同的参数:

subset Prime      of Int   where *.is-prime;
subset BigPrime   of Prime where * >  10_000;
subset SmallPrime of Prime where * <= 10_000;

multi MAIN ( BigPrime   $num ) { say "Prime number! Nice and big"; }
multi MAIN ( SmallPrime $num ) { say "Puny prime number";          }
multi MANI (            $num ) { say "Gimme primes";               }
$ perl6 test.p6 42
Gimme primes!
$ perl6 test.p6 7
Puny prime number
$ perl6 test.p6 31337
Prime number! Nice and big
class Numbers {
    multi method id ( Numeric $num ) { say "$num is a number"       }
    multi method id (         $num ) { say "$num is something else" }
}

Numeric.new.id:  π;
Numbers.new.id: 'blah';

# OUTPUT:
# 3.14159265358979 is a number
# blah is something else

扩展方法的功能性:

class Numbers {
    multi method id ( Numeric $num ) { say "$num is a number"       }
    multi method id (        $num  ) { say "$num is something else" }
}

class SmarterNumbers is Numbers {
    multi method id (Numeric $num where * ==  π ) { say "Mmmm yummy pie!" }
}

SmarterNumbers.new.id: 42;
SmarterNumbers.new.id: π;
SmarterNumbers.new.id: 'blah';

# OUTPUT:
# 42 is a number
# Mmmm yummy pie!
# blah is something else

Custom Terms and Operators

img
sub infix:<¯\(°_o)/¯> {
     ($^a, $^b).pick
 }

say 'Coke' ¯\(°_o)/¯ 'Pepsi';

# OUTPUT:
# Pepsi

操作符分类: infix, prefix, postfix,circumfix, postcircumfix 并且你还能把 term 用于项中。

sub prefix:<∑> (*@els) { @els.sum }
say ∑ 1, 2, 3, 4;

# OUTPUT:
# 1234

看起来并没有很好地起作用...

sub prefix:<∑> (*@els) is looser(&infix:<,>) { @els.sum }
say ∑ 1, 2, 3, 4;

# OUTPUT:
# 10

使用 is looseris tighter 来更改优先级。默认的优先级和那个位置上的 +/++ 操作符的优先级相同。(查看 docs 以使用 is assoc trait 更改结合性。)

One More Example:

 sub term:<ξ> { (^10 + 1).pick; }
 sub postcircumfix:<❨  ❩> ($before, $inside) is rw {
     $before{$inside};
 }

 my %hash = :foo<bar>, :meow<moo>;
 %hash❨'foo'❩  = ξ;
 %hash❨'meow'❩ = ξ;

say %hash;

# OUTPUT:
# foo => 6, meow => 8

重写已经存在的操作符:

sub infix:<+> (Int $a, Int $b) { $a - $b };
say 2 + 2;

# OUTPUT:
# 0
img

不要担心… 这个效果是本地作用域的(lexically scoped!)

img
class Thingamagig { has $.value };

multi infix:<~> (Thingamagig $a, Str $b) {
    $a.value ~ $b
}

my $thing = Thingamagig.new: value => 'thingamagig';
say 'foo' ~ 'bar';
say $thing ~ 'bar';
say 'bar' ~ $thing;

# OUTPUT:
# foobar
# thingamagigbar
# barThingamagig<139870715547680>

查看 Color::Operators 模块获取更多例子。

Hyperspace

Multi-core processing at a touch of a button

img

超运算符

它们看起来像 «» 你能在这儿看到它们的 解释 :

      (1, 2) «+« (3)
      (1, 2) »+» 1
(1, 2, 3, 4) «+» (1, 2)

那些操作符暂时还不是多线程的, if at all。相反, 我要谈论的变体是这个:

@foo».bar

假设你想把数组中的每个字符串都转为大写然后把那个数组分割为子列表, 每个子列表含有 3 个元素:

my @a = <one two three four five six seven eight nine>;
say @a.map({ .uc}).rotor: 3;

# OUTPUT:
# ((ONE TWO THREE) (FOUR FIVE SIX) (SEVEN EIGHT NINE))

很好很简短, 但是假设你想在上千个元素身上调用耗时更多的方法呢?

那么就在方法调用前使用一个 hyper 操作符好了:

my @a =  <one two three four five six  seven eight nine>;
say @a».uc.rotor: 3;

# OUTPUT:
# ((ONE TWO THREE) (FOUR FIVE SIX) (SEVEN EIGHT NINE))

在点号方法调用前面放上一个 » 那么你所调用的方法会在每个元素身上单独调用。链式调用中更远的那个方法会在数组(列表等)身上调用, 除非它们也是 hypered。

Hyper Seqs

假如你想在多核上对一堆东西上"做事情"呢? 遍历一个 HyperSeq。你可以调用下面的两者之一得到一个 HyperSeq:

  • .hyper— 保留元素顺序
  • .race— 不保留元素顺序

遍历一个 4-元素的序列, 每个元素睡眠 1 秒钟:

for (1..4).race( batch => 1 ) {
    say "Doing $_";
    sleep 1;
}
say "Code took {now - INIT now} seconds to run";

# OUTPUT:
# Doing 1
# Doing 3
# Doing 2
# Doing 4
# Code took 1.0090415 seconds to run

代码只是运行了 1秒多!

.hyper 同样, 但是它保留了结果序列中元素的顺序。

Autothreaded junctions

  • Logical superposition of values

某些逻辑检查的代码:

my @valid = <foo bar baz>;
my $what = 'ber';
say "$what is not valid" if not @valid.grep: { $what eq $_ };
say "A ber or a bar"     if $what eq 'ber' or $what eq 'bar';

# OUTPUT:
# ber is not valid
# A ber or a bar
  • Autothreaded junctions
my @valid = <foo bar baz>;
my $what = 'ber';
say "$what is not valid" if $what eq none @valid;
say "A ber or a bar"     if $what eq 'ber' | 'bar';

# OUTPUT:
# ber is not valid
# A ber or a bar
type constructor operator True if ...
all all & 没有值为 False
any any | 至少一个值为 True
one one ^ 完全只有一个值为 True
none none 没有值为 True

最好的部分? Junctions 是自动线程化的(autothreaded), 这意味着编译器能在多个线程上对它们进行求值!

Promises

我不经常写并行化的代码, 但是当我写的时候, 它是这样的简单:

 start { sleep 3; say "two" };
 say "one";
 sleep 5;
 say "three";

# OUTPUT:
# one
# two
# three

并发 / 异步 代码:

my @promises = ^3 .map: {
    start {
        .say; sleep 1;
        $_ * 4;
    }
};
say "Started! {now - INIT now}";
say await @promises;
say "All done! {now - INIT now}";

# OUTPUT:
# 0
# 1
# 2
# Started! 0.0196113
# (0 4 8)
# All done! 1.0188611

Start later:

Promise.in(5).then: -> $v { say "It's been {now - INIT now} seconds!" };
sleep 7;
say "Ran for {now - INIT now} seconds"

# OUTPUT:
# It's been 5.031918 seconds!
# Ran for 7.0160562 seconds

Supplies

异步数据流:

my $supplier = Supplier.new;

$supplier.Supply              .tap: -> $v { say "Original: $v" };
$supplier.Supply.map(  * × 2 ).tap: -> $v { say "  Double: $v" };
$supplier.Supply.grep( * % 2 ).tap: -> $v { say "  Odd: $v"    };

$supplier.emit: $_ for ^3;

# OUTPUT:
# Original: 0
#   Double: 0
# Original: 1
#   Double: 2
#   Odd: 1
# Original: 2
#   Double: 4

Events at interval inside an event loop (react):

react {
    whenever Supply.interval: 2 -> $v {
        say "$v: {now - INIT now}";
        done if $v == 2;
    }
    whenever Supply.interval: 1 -> $v { say "  1 sec: {now - INIT now}"; }
}

 # OUTPUT:
 # 0: 0.026734
 #   1 sec: 0.0333274
 #   1 sec: 1.02325708
 # 1: 2.027192
 #   1 sec: 2.0276854
 #   1 sec: 3.0234109
 # 2: 4.0324349

Channels

一个线程安全的队列:

my $c = Channel.new;
start {
    loop { say "$c.receive() at {now - INIT now}" }
}
await ^10 .map: -> $r {
    start {
         sleep $r;
         $c.send: $r;
    }
}
$c.close;

# OUTPUT:
# 0 at 0.01036314
# 1 at 1.0152853
# 2 at 2.0174991
# 3 at 3.020067105

Grammars

更容易的解析东西的方式。

img
grammar MyGrammar {
    token TOP     { <sign> <digits> <decimal>? }
    token sign    { <[+-]>?                    }
    token digits  { \d+                        }
    token decimal { \. <digits>                }
 }

say MyGrammar.parse: '250.42';

# OUTPUT:
# 「250.42」
#  sign => 「」
#  digits => 「250」
#  decimal => 「.42」
#   digits => 「42」

actions:

grammar MyGrammar {
    token TOP     { <sign> <digits> <decimal>? }
    token sign    { <[+-]>?                    }
    token digits  { \d+                        }
    token decimal { \. <digits>                }
}

class MyActions {
    method sign ($/) { $/.make: $/.chars ?? ~$/ !! '+'                        }
    method TOP  ($/) { $/.make: $<sign>.made ~ ($<digits> + 42 ) ~ $<decimal> }
}

say MyGrammar.parse('250.42', actions => MyActions).made;

# OUTPUT:
# +292.42

有用的模块:

  • Grammar::DebuggerGrammar::Tracer— 使用两者之一来调试你的 grammars 的输出。
  • Grammar::BNF— 自定地把 BNF 转换为 Perl 6 grammars !!

Whatever, man!

Whatever Code, Meta operators, Model6 Object Model, Sets, bags, and mixes

img

Whatever Code

使用 WhateverStar 作为一种快速获取一个带有参数的闭包的方式:

 say (* + 2)(2);
 say <1 25 3 100>.grep: * > 5;
 subset Primes of Int where *.is-prime;
 
 # same as
 
 say sub { $^a + 2 }(2);
 say <1 25 3 100>.grep: { $_ > 5 };
 subset Primes of Int where { $_.is-prime };

每个 WhateverStar 代表着下一个位置参数。你不能使用 WhateverStar 引用同一个参数多于 1 次:

say ( * + * + * )(2, 3, 4);

# OUTPUT:
# 9

n-at-a-time(一次 n 个) .map 从未像这样简单:

say ^12 .map: * + * + *;

# OUTPUT:
# (3 12 21 30)

看, 整个 Fibonacci 序列存在于一个惰性列表中!

my  @fibonacci = 0, 1, * + * … *;
say @fibonacci[42];

# OUTPUT:
# 267914296

, 还有 HyperWhatever!

Just sayin'...

say ( ** + 2 )(^10);
say (  * + 2 )(^10);

# OUTPUT:
# (2 3 4 5 6 7 8 9 10 11)
# 2..^12

Meta Operators

和你把方括号里面的操作符放在列表中的元素之间的效果一样:

say [+] 1, 2, 3;   # 6
say [*] 1..5;      # 120

my @numbers = (2, 4, 3);
say [<] @numbers;  # False

Triangle Reduce: 在两个相继的元素之间使用操作符, 在它的结果和下一个元素之间再次使用操作符:

say [\+] 1, 2, 3;
say [\*] 1..5;

 # OUTPUT:
 # (1 3 6)  ## Breaking it down: 1 (1), 1 + 2 (3), 3 + 3 (6)
 # (1 2 6 24 120)

Perl 6 Object Model

class Foo {
    has $.attr;
    has $.attr-rw is rw;
    has $.attr-required is required;
    has $!attr-private = 42;

    method public   { say $!attr + $!attr-private; }
    method !private { say 'secret' }
}

my $foo = Foo.new: :attr<public>,
                   :attr-required<yup-here-it-is>;

say $foo.attr;
say $foo.public;
$foo.attr-rw = 42;

你也可以指定类型约束和 subset 约束:

class Foo {
    subset Primes of IntStr where *.is-prime;

    has Int    $.attr;
    has Str    $.attr-rw is rw where *.chars < 5;
    has Primes $.attr-required is required;
}

Roles— 安全地为你的类添加行为:

role Drawable {
    method draw { say "Line from $.x to $.y" };
}
class Line does Drawable {
    has $.x;
    has $.y;
}
my $line = Line.new: :42x, :75y;
$line.draw;

# OUTPUT:
# Line from 42 to 75
role Drawable {
    method draw { say "Line from $.x to $.y" };
}
role OtherDrawable {
    method draw { say "It's a draw!" };
}
class Line does Drawable does OtherDrawable {
    has $.x;
    has $.y;
}
my $line = Line.new: :42x, :75y;
$line.draw;

# OUTPUT:
# ===SORRY!=== Error while compiling /home/zoffix/CPAN/TPM-2016/test.p6
# Method 'draw' must be resolved by class Line because it exists in multiple
# roles (OtherDrawable, Drawable) at /home/zoffix/CPAN/TPM-2016/test.p6:7

MOP: Meta Object Protocol

自省和 Perl 6 对象系统

img
#| Just 'cause
class TestStuff {};
my $x = TestStuff.new;
say $x.WHAT;     # (TestStuff)  # The type object of the type
say $x.WHICH;    # TestStuff|179689128 # The object's identity value
say $x.WHO;      # TestStuff # The package supporting the object
say $x.WHERE;    # -1225903068 # The memory address of the object (not stable)
say $x.HOW;      # Perl6::Metamodel::ClassHOW.new # The metaclass object
say $x.WHY;      # Just 'cause # The attached Pod value.
say $x.DEFINITE; # True # Returns True for instances and False for type objects

为已存在的类添加方法:

Int.^add_method('x', -> $class, $v { say $v });
constant A := Metamodel::ClassHOW.new_type( name => 'A' );
A.^add_method('x', -> $class, $v { say $v });
#A.^compose;

A.x: 'A class';
Int.x: 'Int class';

Sets, Bags, and Mixes

Immutable:

  • Set—不同对象的集合
  • Bag—带有整数系数(权重)的不同对象的集合
  • Mix—带有实际系数(权重)的不同对象的集合

Mutable:

  • SetHash—不同对象的集合
  • BagHash—带有整数系数(权重)的不同对象的集合
  • MixHash—带有实际系数(权重)的不同对象的集合

对东西进行计数? 一个 Bag 就做到了:

.say for 'This is just a sentence'.comb.Bag;

# OUTPUT:
# n => 2
# a => 1
#   => 4
# c => 1
# j => 1
# s => 4
# T => 1
# e => 3
# t => 2
# i => 2
# u => 1
# h => 1

使用集合操作符写简明代码:

my $valid = set <foo bar ber boor>;
my @given = <foo meow bar ber>;

say ‘Something's wrong’ unless @given ⊆ $valid;

并集和差集:

say <foo bar> ∪ <bar meow>;  # Union operator
say <foo bar> ⊖ <bar meow>;  # Symmetric set difference operator

# OUTPUT:
# set(foo, bar, meow)
# set(foo, meow)

查看 the docs 获取完整的操作符列表。

Polyglot

在 Perl 6 使用其它语言!

NativeCall

不用写任何 C 代码就可以使用 C libraries!!

(或多或少)

标准 C library:

use NativeCall;
sub fork is native {};
fork;
say $*PID;

# OUTPUT:
# 11274
# 11275

BTW: A Safety Tip

在标准 C 库中有一个 system

使用 C library:

class STMT is repr('CPointer') { };
sub sqlite3_column_text(STMT, int32)
    returns Str
    is native('sqlite3', v0) { };
int8           (int8_t in C, also used for char)
int16          (int16_t in C, also used for short)
int32          (int32_t in C, also used for int)
int64          (int64_t in C)
uint8          (uint8_t in C, also used for unsigned char)
uint16         (uint16_t in C, also used for unsigned short)
uint32         (uint32_t in C, also used for unsigned int)
uint64         (uint64_t in C)
long           (long in C)
longlong       (long long in C, at least 64-bit)
num32          (float in C)
num64          (double in C)
Str            (C string)
CArray[int32]  (int* in C, an array of ints)
Pointer[void]  (void* in C, can point to all other types)
bool           (bool from C99)
size_t         (size_t in C)

使用 App::GPTrixie 把 C 头文件转换为 Perl 6 子例程定义:

$ gptrixie --all /usr/local/include/gumbo.h

## Enumerations
enum GumboNamespaceEnum is export (
   GUMBO_NAMESPACE_HTML => 0,
   GUMBO_NAMESPACE_SVG => 1,
   GUMBO_NAMESPACE_MATHML => 2
);
enum GumboParseFlags is export (
   GUMBO_INSERTION_NORMAL => 0,
   GUMBO_INSERTION_BY_PARSER => 1,

   ...

Inline::Perl5

在 Perl 6中使用任意 Perl 5 模块!

use Inline::Perl5;
use Mojo::DOM:from<Perl5>;
 
my $dom = Mojo::DOM.new: '<p><b>This is awesome</b>, trust me</p>';
 
say $dom.at('b').all_text;

# OUTPUT:
# This is awesome
  • 支持 Perl 5 模块, 包括 XS 模块。
  • 允许在 Perl 5 和 Perl 6 之间传递整数、字符串、数组、散列、代码引用、文件句柄和对象。
  • 支持从 Perl 6 中在 Perl 5 对象上调用方法并且支持从 Perl 5 中在 Perl 6 对象上调用方法。
  • 在 Perl 6中子类化 Perl 5 的类。

使用一堆其它语言...

你和我展示的可能有点不同:

img

Simple Things:Hacking on the Perl 6 Compiler

听起来很疯狂...

Perl 6 大部分是用 Perl 6 写的!

这意味着...

一般的 Perl 6 使用者可以使 Perl 6 变得更好!

Perl 6 is Written in Perl 6

How??

基础是用 NQP 写的 (Not Quite Perl):https://github.com/perl6/nqp

其它的是用 Perl 6 写的: https://github.com/rakudo/rakudo

那么解析呢...?

是的, 仅仅是一个 Perl 6 Grammar:

Bonus Slides

并发代码中的错误

错误在哪一行?

my $promise = start {
    say 0/0;
    # A whole
    # bunch
    # of other code
};
 
say await $promise;

# OUTPUT:
# Attempt to divide by zero using div
#   in block <unit> at test.p6 line 8

包含一个花括号:

 1: my $promise = start {
 2:     say 0/0;
 3:     # A whole
 4:     # bunch
 5:     # of other code
 6:     CATCH { warn .backtrace };
 7: };
 8:
 9: say await $promise;

# OUTPUT:
#   in block  at test.p6 line 2
#   in block  at test.p6 line 6
# Attempt to divide by zero using div
#   in block <unit> at test.p6 line 9

有理数!

Rat 是一种 Perl 6 类型, 它由分子和分母表示:

my $x = 0/0;
say 'Universe is still unimploded';
say sin $x;

# OUTPUT:
# Universe is still unimploded
# NaN

实际的数字只在需要时计算:

my $x = 0/0;
say 'Universe is still unimploded';
say $x;

# OUTPUT:
# Universe is still unimploded
# Attempt to divide by zero using div
#   in block <unit> at test.p6 line 3
#
# Actually thrown at:
#   in block <unit> at test.p6 line 3

Proc::Async

Async 和其它程序通信:

my $proc = Proc::Async.new: :w, 'grep', 'foo';
$proc.stdout.tap: -> $v { print "Output: $v" };

say 'Starting grep process...';
my $promise = $proc.start;
    $proc.say: 'this line has foo';
    $proc.say: "this one doesn't";
    $proc.close-stdin;
await $promise;
say 'Done.';

# OUTPUT:
# Starting grep process...
# Output: this line has foo
# Done.

不要 say 太多!

say 函数/方法用于展示人类可读的简明信息并调用对象的 gist 方法。如果你想输出一大堆东西, 那么使用 put 函数/方法:

^101 .say;
(0..100).list.say;
say '----------';
^101 .put;
(0..100).put;

# OUTPUT:
# ^101
# (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 ...)
# ----------
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

更有用的对象

当使用say-ed, put-ed, 或其它任何东西时, 让你的对象更加准确地工作:

class Thingamagig {
    method gist    { 'Brief info'        }
    method Str     { 'Not so brief info' }
    method Numeric { 42                  }
}

my $thing = Thingamagig.new;
say $thing;
put $thing;
say $thing + 2;

# OUTPUT:
# Brief info
# Not so brief info
# 44

内置的性能分析器

仅仅在命令行上指定 --profile 标记, 就会为你生成 HTML 格式的结果文件。

$ perl6 --profile test.p6

谢谢!

Any Questions?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,558评论 18 399
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,368评论 25 707
  • 2009 有用的和有意思的循环 让我们来看一个基本的例子. 这是一个最简单清晰的语法的例子.在这并没有使用括号来包...
    焉知非鱼阅读 534评论 0 0
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,846评论 6 13
  • 2017年3月8日,刚坐完月子的我跑到厦门和姐妹们过了一个难忘的女王节。姐妹们互相分享了各自的爱情感悟后,大家抱头...
    老李课堂阅读 5,710评论 0 0