Perl 6 FAQ

2016-10-20 号更新。

源文件可以在 githubperl6.org上找到.

General

Rakudo 和 Perl 6 的区别是什么?

Rakudo 是 Perl 6 的一个实现。目前它是完成度最好的但是过去也有其它的实现, 将来也可能会有其它实现。Perl 6 是语言的定义。很多场合

这两个名字可以宽松地使用并互相替换。

会有 Perl 6 版本 6.0.0 吗?

第一个稳定语言版本的版本称为 v6.c,而不是 6.0.0。 不同的命名方案使得不太可能发布具有精确版本 6.0.0 的语言。

您可以使用下面的代码检查您的 Rakudo 编译器是当前至少是什么版本(注意这可能不是真正的供应商二进制文件):

perl6 -e 'say q[too old] if $*PERL.version before Version.new(q[6.c])'

它首先由 Rakudo Perl 6 编译器版本的 2015.12 实现,并且可能通过使用 'use 6.c' 指令在可预见的未来支持后续版本。 下一个语言版本(无发布日期)为 v6.d.

作为一个 Perl 6 初学者我应该安装什么?

如果你是一个 Linux 或 Mac 用户, 你可能需要下载 Rakudo Star 并通过编译 MoarVM 版本安装(一个简单的处理)

如果你是一个 Windows 32 或 64 位用户, 那么 Rakudo Star 二进制版本在 rakudo 网站也能获得。你需要 Windows Git 来使用 panda。

Linux 和 Mac 二进制版本稍后也可能从供应商和第三方那儿获取到。尽管供应商版本可能过时了。

或者有一个官方的 rakudo star Docker 镜像, 地址为 https://hub.docker.com/_/rakudo-star/

作为一个中高级用户我想跟进 Rakudo 开发

安装类似于 Perl 5 的 perlbrew -- rakudobrew , 同等的 Python 还有 Ruby 工具。

从哪里能找到关于 Perl 6 的好文档?

最令人信赖的信息能在 perl6.org 或那儿的直接链接。

你也可以使用 Google 搜索 Freenode #perl6 IRC 频道。

http://www.perl6.org/documentation/http://doc.perl6.org/

什么是 Perl 6 spec?

"spec" 指的是 Perl 6的官方测试套件。它被称作 roast 并被托管在 github 上.

它被用来测量一个 Perl 6 的实现有多彻底。

有没有 Perl 6 的术语相关的项目?

查看 glossary

我是一个 Perl 5 程序员. Perl 5 和 Perl 6 的区别在哪儿?

https://docs.perl6.org/language/5to6-nutshell 下面查看 ‘5to6-nutshell’ pod 文档和相关页面。

模块

Perl 6 有 CPAN 吗? 或者 Perl 6 会使用 Perl 5 的 CPAN 吗?

Perl 6 还没有像 CPAN 那样成熟的模块仓库. 但是 modules.perl6.org 有很多已知的 Perl 6 模块, panda 能在 Rakudo 上安装这些模块.

我能在 Perl 6 中使用 Perl 5的模块吗?

使用 Inline::Perl5 能让大部分 Perl 5 模块工作, 它甚至能很好地运行 Perl 5 的 Catalyst 和 DBI。

我能在 Perl 6 中使用 C 和 C++ 吗?

Nativecall 让这个特别容易。

Nativecall 找不到 libfoo.so 并且我只有 libfoo.so.1.2!

这在 Debian 那样的系统中很常见。 你需要安装 "libfoo-dev" 来为丢失的文件设置符号链接。

所有的传统 Unix 库函数去哪儿了?

使用 Nativecall 访问它们很容易。
POSIX 模块也可以。

Rakudo 有核心标准库吗?

Rakudo 是一个包含最小电量的编译器发布(Test 和 Nativecall等等),像 linux 内核一样。

Rakudo Star 是一个带有一些有用模块的 rakudo, 并且更多的模块可以从生态系统里安装。

有像 B::Deparse 那样的东西吗?/我怎么抓住 AST?

使用 perl6 --target=ast -e 'very-short-example()' 来抓取编译单元的抽象语法树(AST)。

语言特性

我怎么 dump Perl 6 的数据结构(就像 Perl 5 的 Data::Dumper 和类似的)?

examples:


my $foo="bar"
dd $foo        # Str $foo = "bar"
say :$foo.perl # :foo("bar")
say :$foo.gist # foo => bar

生态系统中还有模块来做这个事情, 例如 Data::Dump 使用颜色来 Dump。

我怎么在 Perl 6 提示符(REPL)中找到历史命令行?

从生态系统中安装 Linenoise.

作为一种选择, 在 UNIX 那样的系统中可以安装 rlwrap。这在类 Debian 系统中可以通过apt-get install rlwrap 安装。

为什么 Rakudo 编译器有时候报错更友好?

如果在输出中出现 SORRY! , 则错误是编译时错误, 否则是运行时错误。

Examples:


say 1/0     # Attempt to divide 1 by zero using div

sub foo ( Int $a, Int $b ) {...}
foo(1)      # ===SORRY!=== Error while compiling ...

什么是 (Any)?

Any 是一个用于新类的默认超类(superclass)的顶层类。
它经常在这样的上下文出现:变量被定义但没有被赋值, 这里它类似于其它语言中的 undef 或 null 值。

examples:

my $foo;
say $foo;       # (Any) 注意圆括号表明的类型对象
say $foo.^name  # Any

(Any) 不应该被用于检查 definedness。 在 Perl 6 中, definedness 可能是一个对象的属性。 通常实例是被定义的, 而类型对象是未定义的。

say 1.defined       # True
say (Any).defined   # False

so 是什么?

so 是一个松散优先级的操作符, 它强制上下文为 Bool.

so 拥有和 ? 前缀操作符同样的语义, 就像 and&& 的低优先级版本一样.

用法示例:

say so 1|2 == 2;    # Bool::True

在这个例子中, 比较的结果(结果是 Junction)在打印之前被转换为 Bool 值了.

签名中的那些 :D 和 :U 是什么东东?

在 Perl 6 中, 类和其它类型是对象, 并且传递自身类型的类型检测。
例如如果你声明一个变量

my Int $x = 42;

那么, 你不仅可以给它赋值整数(即, Int 类的实例), 还能给它赋值 Int 类型对象自身:

$x = Int

如果你想排除类型对象, 你可以追加一个 :D 类型微笑符, 它代表"定义"(definite):

my Int:D $x = 42;
$x = Int;  # dies with:
           # Type check failed in assignment to $x;
           # expected Int:D but got Int

同样地, :U 约束为未定义的值, 即类型对象。
要显式地允许类型对象或实例, 你可以使用 :_

签名中的 --> 是什么东东?

--> 是一个返回值约束, 要么是类型要么是有定义的值。

类型约束的例子:

sub divide-to-int( Int $a, Int $b --> Int ) {
        return ($a / $b).narrow;
}

divide-to-int(3, 2)
# Type check failed for return value; expected Int but got Rat

有明确返回值的例子:

sub discard-random-number( --> 42 ) { rand }
say discard-random-number
# 42

在这种情况下,最终值被抛弃,因为已经指定了返回值。

Any 和 Mu 的区别是什么?

Mu 是所派生出的所有其它类型的基类型. Any 是从 Mu派生来的, 代表着任何类型的 Perl 6 值. 主要区别是, Any 不包含 Junction.

子例程参数的默认类型是 Any, 以至于当你声明 sub foo ($a) 时, 你真正表达的是 sub foo (Any $a) . 类似地, 类的声明被假定继承自 Any, 除非使用了像 is Mu 这样的 trait 特征.

怎么从 Junction 中提取值?

如果你想从 Junction 中提取值(特征态), 那你可能正误入歧途. 应该使用 Set 代替

Junctions 作为匹配器, 而不是使用它们做代数.

如果你还是想那样做, 你可以滥用自动线程(autothreading):

sub eigenstates(Mu $j) {
    my @states;
    -> Any $s { @states.push: $s }.($j);
    @states;
}

say eigenstates(1|2|3).join(', ');
# prints 1, 2, 3 or a permutation thereof

如果 Str 是不可变的, 那么 s/// 是怎么工作的? 如果 Int 是不可变的, $i++ 是怎么工作的?

在 Perl 6 中, 很多基本类型是不可变的, 但是保存它们的变量不是. s/// 作用于变量上, 在这个变量中放入一个新创建的字符串对象. 同样地, $i++ 作用于 $i 变量上, 而不是作用在它里面的值身上.

更多详情请查看: containers 文档。

什么是数组引用和自动解引用? 我仍然需要 @ 符号吗?

在 Perl 6 中, 几乎所有的东西都是引用. 所以谈论 taking references 没有多大意义. 不像 Perl 5 那样, Perl 6 的标量变量也能直接包含数组:

my @a = 1, 2, 3;
say @a;                 # "1 2 3\n"
say @a.WHAT;            # (Array)

my $scalar = @a;
say $scalar;            # "1 2 3\n"
say $scalar.WHAT;       # (Array)

最大的区别是, 标量中的数组在列表上下文中是一个值, 然而数组会被愉快地迭代:

my @a = 1, 2, 3;
my $s = @a;

for @a { ... }          # loop body executed 3 times
for $s { ... }          # loop body executed only once

my @flat = flat @a, @a;
say @flat.elems;        # 6

my @nested = flat $s, $s;
say @nested.elems;      # 2

你可以使用 @( ... ) 或通过在表达式身上调用 .list 方法来强制展平, 使用 $( ... ) 或通过在表达式身上调用 .item 方法强制为 item 上下文(不展平).

为什么还要符号? 你不能没有它们吗?

有几个原因:

  • 它们使插值变量到字符串中变得更容易
  • 它们为不同的变量和 twigils 组成了微型命名空间, 因此避免了名字冲突
  • 它们允许简单的 单数/复数 区别
  • 它们像使用强制性名词标记的自然语言一样工作,所以我们的大脑为处理它而生
  • 它们不是强制性的,因为你可以声明无符号名字(如果你不介意含糊不清)

"类型 Str 不支持关联索引"

你可能会把字符串插值和 HTML 搞混。

my $foo = "abc";
say "$foo<html-tag>";

Perl 6 认为 $foo 是一个散列而 <html-tag> 是一个字符串字面量的散列键。使用闭包来帮助你理解吧。

my $foo = "abc";
say "{$foo}<html-tag>";

Perl 6 有协程吗? 什么是 yield ?

Perl 6 没有 Python 那样的 yield 语句, 但是它通过惰性列表却能提供类似的功能. 有两种很潮的方式来写出能返回惰性列表的例程:

# first method, gather/take
my @values := gather while have_data() {
    # do some computations
    take some_data();
    # do more computations
}

# second method, use .map or similar method
# on a lazy list
my @squares := (1..*).map(-> $x { $x * $x });
# or
my @squares = (1..*).map(-> \x { x² });

为什么我需要反斜线(unspace)在多行上分割方法调用?

(请在这儿添加答案)

为什么我不能从 new 方法初始化私有属性, 我怎么修复它?

这样的代码:


class A {
    has $!x;
    method show-x {
        say $!x;
    }
}
A.new(x => 5).show-x;

不会打印出 5. Private 属性是私有的, 这意味着私有属性在外面是不可见的. 如果默认的构造器能够初始化私有属性, 那么这些私有属性就会泄露到公共 API 中.

如果你仍旧想让它工作, 你可以添加一个 submethod BUILD 来初始化它们:

class B {
    has $!x;
    submethod BUILD(:$!x) { }
    method show-x {
        say $!x;
    }
}
A.new(x => 5).show-x;

BUILD 由默认的构造器使用用户传递给构造器的所有具名参数调用(间接地, 更多细节查看Object Construction)。 :$!x 是名为 x 的具名参数, 当使用名为 x 的具名参数来调用时, 它的值被绑定到属性 $!x 上.

但不要这样做。如果名字是 public 的,使用 $.x 以那样的方式声明没有什么不好,因为默认情况下外部视图是只读的(readonly),你仍然可以使用 $!x 从内部访问它。

say, put 和 print 怎么不同, 为什么不同?

最明显的区别是, sayput 在输出后面添加了一个换行符, 而 print 没有.

但是还有另外一个区别: printput 通过对每一个传递来的 item 调用 Str 方法来把它的参数转换为字符串, 相反, say 使用 gist 方法. 前者是为计算机设计的, 后者是为人类.

或者它俩被解析的方式不同, $obj.Str 给出一个字符串表示, $obj.gist 是对象的一个简短总结, 适合编程人员的快速识别, $obj.perl 打印一个 Perlish 的表示.

例如, 类型对象, 也是熟知的 “未定义值”, 字符串化为一个空的字符串和警告, 而 gist 方法返回由一对圆括号包裹的类型的名字.(用于表明除了类型之外什么也没有).

my Date $x;     # $x now contains the Date type object
print $x;       # empty string plus warning
say $x;         # (Date)\n

所以, say 优化的用于调试和向人们展示, printput 更适合于产生用于其它程序的输出.

put 因此是 printsay 之间的一种混合; 像 print, 它的输出适合于其它程序, 也像 say, 它在输出的末尾添加了换行符。

token 和 rule 之间的区别是什么?

regex , tokenrule 这三个都引入了正则表达式, 但是语义略微有一点不同.

token 隐含了 :ratchet:r 修饰符, 这防止了 rule 的回溯.

rule 隐含了 :ratchet:sigspace (缩写为 :s)修饰符, 这意味着规则(rule)不会回溯, 并且它把 regex 的文本中的空白当作 <.ws> 调用(例如匹配空白, 除了在两个单词字符之间之外, 它是可选的). regex 开头的空白和备选分支中每个分支开头的空白会被忽略.

regex 声明一个简单的正则表达式,没有任何隐含的修饰符。

die 和 fail 之间的区别是什么?

die 抛出一个异常.

fail 返回一个 Failure 对象。 (如果调用者已经声明了 use fatal; 在调用作用域中, fail 会抛出一个异常而不返回)

Failure 是一个 “未知的” 或 “懒惰的” 异常.它是一个含有异常的对象, 当这个 Failure 被用作普通的对象或者在 sink 上下文中忽略它时, 则会抛出一个异常.

Failure 从 defined 检查中返回 False, 并且你可以使用 exception 方法提取出异常.

为什么 wantarray 或 want 不见了? 我能在不同的上下文中返回不同的东西吗?

Perl 拥有 wantarray 函数来告诉你这是在空上下文, 标量上下文,还是在列表上下文中调用的. Perl 6 没有与之等价的结构, 因为上下文不是向内流动的, 例如, 子例程不知道调用所在的上下文.

一个愿意是因为 Perl 6 有多重分派, 在这样一个例子中:

multi w(Int $x) { say 'Int' }
multi w(Str $x) { say 'Str' }
w(f());

没办法决定子例程 f 的调用者想要一个字符串还是想要一个整数, 因为它还不知道调用者是什么. 通常这要求解决 halting 问题, 在这个问题上, 即使写 Perl 6编译器的人也会遇到麻烦.

在 Perl 6 中达到上下文敏感的方式是返回一个知道怎样响应方法调用的对象.

例如, regex 匹配返回 Match 对象, 该对象知道怎样响应列表索引, 散列索引, 并能变成匹配的字符串.

Pointer 和 OpaquePointer 的区别是声明?

OpaquePointer 被废弃了并且已经用 Pointer 代替了。

Perl 6 实现

哪个 Perl 6 的实现是可用的?

当前开发最好的是 Rakudo(使用多个虚拟机后端)。历史上的实现还包括 Niecza (.NET) 和 Pugs (Haskell). 其它的列出在 Perl 6 Compilers 下面。

Rakudo 是用什么语言写的?

NQP 是(1)NQP 代码,(2)底层虚拟机使用的任何语言,(3)一些第三方 C 和 Java 库,以及(4)早期运行构建过程创建的一些引导文件的混合 。

为什么我不能把所有的数值都赋值给 Num 类型的变量?

my Num $x = 42;
# dies with
# Type check failed in assignment to '$x'; expected 'Num' but got 'Int'

Num 是浮点类型, 与 integers 不兼容. 如果你想要一个允许任何数字值的类型约束, 使用 Numeric (它也允许复数), 或 Real如果你想排除复数.

元问题和宣传

Perl 6 什么时间会准备好? 就是现在吗?

编程语言和它们的编译器的准备就绪不是一个二元决策. 因为它们(语言和实现)能进化, 它们平稳地发展变得更可用. 根据你对编程语言的要求, 它可能适合也可能不适合你.

请查看 功能对比矩阵 了解更详尽的实现了的功能.

请注意, Larry Wall 已经在 FOSDEM 2015 会议上宣布, 一个产品级的 Rakudo Perl 6 将会在 2015 圣诞节发布.

为什么我要学习 Perl 6? 它有什么了不起的吗?

Perl 6 统一了很多其它编程语言中不经常有的伟大想法. 虽然其中的几种语言提供了其中的某些功能, 但是没有提供全部.

不像大部分语言那样, 它提供了:

  • Perl 6 提供了过程式的, 面向对象的和函数式编程方法。
  • 易于使用的一致性语法, 数据结构中的符号不变性。
  • 完全基于字素的 Unicode 支持, 包括附件 #29
  • 足够清晰的正则表达式, 更易读, 更多功能。
  • Junctions 允许多个可能性的简单检测, 例如 $a == 1|3|42(意思是 $a 等于 1 或 3 或 42)
  • 相对于全局变量, 动态作用域变量提供了词法作用域备选
  • 强调可组合性和本地作用域以阻止「超距作用」。例如, imports 总是本地作用域的。
  • 易于理解的一致性作用域规则和闭包
  • 强大的面向对象, 含有类和 roles(所有的东西都可以当做对象)。继承、子类型、代码复用。
  • 内省到对象和元对象中(叠罗汉)
  • 元对象协议允许元编程而不需要生成/解析代码。
  • 子例程和方法签名,便于解包位置参数和命名参数。
  • 根据元数,类型和可选的额外代码使用不同的签名对同一具名子例程/方法进行多重分派。
  • 未知子例程/不可能的分派在编译时给出错误报告。
  • 可选的渐进类型检查,无需额外的运行时成本。 还有可选类型注解。
  • 基于对编译器/运行时状态的内省的高级错误报告。这意味着更有用,更精确的错误信息。
  • Phasers(如 BEGIN/END) 允许代码作用域 进入/退出, 首次循环/last/next 和其它更多上下文中执行。
  • 高级并发模型,用于隐式以及显式多进程处理,这超越了原始线程和锁。 Perl 6 的并发提供了一组丰富的(可组合的)工具。
  • 多核计算机越来越多地被使用,由于并行性使得 Perl 6 可以使用多核,包括隐式(例如使用>>.方法)和显式 (start {code}) 。这很重要,因为摩尔定律正在结束。
  • 提供结构化语言支持以实现异步执行代码的编程。
  • Supplies 允许在发生某些事情时执行代码(如定时器,信号或文件系统事件)。
  • react/whenever/supply 关键字允许容易地构建交互式,事件驱动的应用程序。
  • 懒惰求值,如果可能的话,急切求值当需要或必要时。这意味着,例如,惰性列表,甚至无限延迟列表,如斐波纳契序列或所有素数。
  • 原生数据类型用于更快的处理
  • 使用 NativeCall 连接到 C/C++ 中的外部库非常简单。
  • 使用 Inline::Perl5 和 Inline::Python 连接 Perl 5(CPAN)/Python 非常简单。
  • 可以同时安装和加载模块的多个版本。
  • 由于更简单的更新/升级策略,简化了系统管理。
  • 简单的数值计算没有损失精度,因为 Rats(有理数)。
  • 用于解析数据或代码的可扩展语法(Perl 6 用它解析自身)
  • Perl 6 是一种非常易变的语言(定义自己的函数,运算符,traits 和数据类型,为您修改解析器)。
  • 很多的数据类型选择,加上创建自己的类型的可能性。
  • 具有适当边界检查的多维成型的和/或原生数组
  • 在某个匹配出现时, 词法解析期间随时执行代码
  • 添加自定义运算符或添加 trait 特征和编写子例程一样简单。
  • 在任何运算符(系统或自定义添加的)上自动生成超运算符。
  • 运行在各种后端上。目前 MoarVM 和 JVM,JavaScript在开发中,可能会有更多。
  • 执行期间(JIT)热代码路径的运行时优化。
  • 运行在小型(例如 Raspberry Pi)和大型多处理器硬件上。
  • 基于垃圾收集:没有及时销毁,所以引用计数没有必要。使用 phasers 用以及时的动作。
  • 方法可以在运行时混合到任何实例化的对象中,例如。以允许添加带外数据。
  • 通过使用具有多重分派和自动生成使用信息的 MAIN 子例程,使命令行接口易于访问。
  • 更少的代码行创建更紧凑的程序。名字的霍夫曼编码允许更好的可读性。
  • 使用简单的迭代器接口定义的惰性列表,任何类可以通过最小化的提供单个方法来提供。
  • Perl 6 的座右铭与 Perl一直保持不变:Perl是不同的。简而言之,Perl旨在"使容易的工作变得容易,使困难的工作变得可能"。和"条条大路通罗马"。现在有更多 -Ofun 添加进来。

请查看 功能比较矩阵 获取更多信息.

为什么不把它叫做除了 Perl 以外的其它东西?

很多人建议, Perl 6 跟之前的 Perl 版本的区别太大了, 我们应该考虑给它改名, 或者考虑到 Perl 6 伤害了 Perl 5, 仅仅拥有同样的名字却有更高的版本号.

Perl 6 仍然叫做 “Perl" 的主要原因是:

  • Perl 6 仍然是一个 perlish 风格的语言, 和之前的版本遵守相同的底层思想(用于微型命名空间的符号, 条条大路通罗马, 吸收了很多自然语言的思想..)
  • Perl 6 的代码很 perlish.
  • Perl 仍然是一个强健的品牌名, 我们不想马上抛弃它
  • 找到一个替代的名字很困难. 而且, “camelia” 和 “rakudo" 不是合适的编程语言名
  • 即使 Perl 6 更改了它的名字, Perl 5 也不大可能增加它的版本号为 6.因为 Perl 6 已经根植于人们的头脑中了

Perl 6 对我来说足够快了吗?

那取决于你正在做什么。Perl 6 一直奉行“做对的事情然后做的更快”的哲学进行开发。对于某些东西来说它够快了, 但是需要做的更多。
Perl 6 大部分是由志愿者开发的, 但是 Perl 6 的性能在不久的将来有待提高, 因为 MoarVM 后端包含一个现代的即时(JIT)编译器。
Perl 5 程序员应该意识到 Perl 6 在面向对象方面有很多内建函数并且还有更多其它的。
简单的基准测试会误导除非你在你的 Perl 5脚本中包含了诸如 Moose, 类型检测模块等。

下面这个粗超的基准测试, 使用了所有诸如此类的一般说明, 能展示 Perl 6 在某些类似任务上能和 Perl 5的速度接近。
在你的系统上尝试下, 你可能会感到很惊讶!

# Perl 6 version
use v6;

class Foo { has $.i is rw };

for (1..1_000_000) -> $i {
    my $obj = Foo.new;
    $obj.i = $i;
}

# Perl 5 version
package Foo;
use Moose;

has i => (is => 'rw');

__PACKAGE__->meta->make_immutable;

for my $i (1..1_000_000) {
    my $obj = Foo->new;
    $obj->i($i);
}

1;

# Another Perl 5 version that offers bare-bones set of features
# compared to Moose/Perl 6's version but those are not needed in this
# specific, simple program anyway.
package Foo;
use Mojo::Base -base;

has 'i';

for my $i (1..1_000_000) {
    my $obj = Foo->new;
    $obj->i($i);
}

1;

# A perl program which works under both perl5 (with perl -Mbigint)
# and perl6

my ($prev, $current) = (1, 0);

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

推荐阅读更多精彩内容