Temple run

拯救你的局部变量

你正在rustc迷宫中寻宝,忽然你撞上了一堵墙,上面写着:

这是你妄图将局部变量借走(出其作用域)的证据,你无法逃出borrow checker的法眼,眼看便被困在此处,无法逃脱。局部变量的生命过于短暂,你要借走它,你就不可以让它轻易狗带,你要拯救它。

你摸摸口袋,摸索出一张破旧的羊皮纸,上面歪歪扭扭地写着一些字,看来上面写的是逃生的提示:

 

带走它!

俗话说,“你借不走它,便带走它”。(并没有这样一句俗话)

这大概是最直接的方法,直接把局部变量返回出来,然后再借也不迟。

但是你并不是常山赵子龙,这样的方法不能让你七进七出:

这时你又撞上了写着同样文字的墙(又或者是另外一个写着不能同时存在可变和不可变的借用),这时循环拦住了你们。

不过你可以一次性将所有的局部变量打包带走,再慢慢借:

这是个好方法,但有很大的局限性,你并不怎么喜欢使用这样的方法。因为稍不注意,又该碰壁。

 

懂得分享

分享是一种美德,分享也可解决问题。

你要与rustc达成协议,这个变量你与callee共同拥有:

这的确是一个简单的方法,但是这样的共享是有代价的(而且我不认为这是使用Rc的场景)。而且你听喵老大说,“在API中出现Rc的那一刻,你就输了”。你并不想输。

 

以退为进

俗话说,”退一步海阔天空“。选择后退并不是逃避,不是妥协,而是解决问题的一种智慧。

你不打算继续逃走,而是退后一步选择向迷宫的深处进发,你相信迷宫深处会有出口:

但迷宫深处等待你的可能不是出口,而是万丈深渊,那时候将万劫不复(stackoverflow)

 

交给Arena

Arena是一个区域,是用来存放无处安置的流浪者的。你可以把局部变量放在那里:

arena里面存在着一些规则以外的机制,你并不想将局部变量交给他。(我觉得用了就很不Rusty。而且多了一个额外的东西并不好看)

 

自主可控

目之所见,皆为clone。全部地方都拥有自己的一份。

这虽是最安全的方法,但很显然,这花销十分昂贵,你不希望支出大于收入(指rust的性能)。

结局

这其实是一个关于ownership分配的问题。

1和4是将ownership交给caller;

2将ownership交给Rc等智能指针(Cow同理,但这场景更不合理);

5所有地方都拥有ownership

3将callee转换为caller,ownership不需要变化了。

3和4都会在同一时刻一起析构所有”暂存“的值,相当于不管理,这是个潜在问题。

 

  1. 心智负担很大
  2. 多余的共享的开销,可能入侵到API
  3. 调用开销,容易爆栈,影响API设计
  4. Arena内有锁等等的开销
  5. clone开销太大

你不喜欢以上的所有方法,那么怎么办呢,你发出了求救。(rust还是💊吧(狗头))。