.. _temporary: =============== 临时类型 =============== 临时类型旨在解决数据的生命周期问题,这些问题直接从 C++ 公开给 Daslang。 让我们回顾一下下面的 C++ 示例:: void peek_das_string(const string & str, const TBlock> & block, Context * context) { vec4f args[1]; args[0] = cast::from(str.c_str()); context->invoke(block, args, nullptr); } 此处的 C++ 函数公开了指向 c-string 的指针 a,位于 std::string 内部。 从 Daslang 的角度来看,函数的声明是这样的:: def peek ( str : das_string; blk : block<(arg:string#):void> ) 其中 string# 是 Daslang 字符串类型的临时版本。 临时类型背后的主要思想是它们不能 “转义” 到它们所传递给的块的范围之外。 临时值通过遵循某些规则来实现此目的。 临时值无法复制或移动:: def sample ( var t : das_string ) { var s : string peek(t) $ ( boo : string# ) { s = boo // 错误,无法复制临时值 } } 临时值不能返回或传递给函数,这些函数需要常规值:: def accept_string(s:string) print("s={s}\n") def sample ( var t : das_string ) peek(t) $ ( boo : string# ) { accept_string(boo) // 错误 } } 这会导致以下错误:: 30304: no matching functions or generics accept_string ( string const&# ) candidate function: accept_string ( s : string const ) : void invalid argument s. expecting string const, passing string const&# 值需要标记为 ``implicit`` 才能接受临时值和常规值。 这些函数隐式承诺不会以任何形式缓存 (复制、移动) 数据:: def accept_any_string(s:string implicit) { print("s={s}\n") } def sample ( var t : das_string ) { peek(t) $ ( boo : string# ) { accept_any_string(boo) } } 临时值可以并且打算被克隆:: def sample ( var t : das_string ) { peek(t) $ ( boo : string# ) { var boo_clone : string := boo accept_string(boo_clone) } } 返回临时值是不安全的作。 可以通过 ``safe_addr`` 宏接收相应范围的临时值的指针:: require daslib/safe_addr def foo { var a = 13 ... var b = safe_addr(a) // b 是 int?#,并且此作不需要 unsafe ... }