你如何在'其他'中生锈的默认#[cfg]目标?

时间:2014-12-11 08:37:44

标签: rust

#[cfg]帮助器非常模糊,并没有特别好记录,但通过挖掘librustc我有一个非常合理的所有可用配置目标列表(target_os,target_family,target_arch,target_endian,target_word_size,windows ,unix),当然你可以使用not(..)来指定组合。

但是,我无法弄清楚如何进行“默认”实施。

有没有办法使用cfg做到这一点?

#[cfg(???)] <--- What goes here?
fn thing {
  panic!("Not implemented! Please file a bug at http://... to request support for your platform")
}

#[cfg(target_os = "mac_os"]
fn thing() {
  // mac impl 
}

#[cfg(target_os = "windows"]] 
fn thing() {
  // windows impl
}

我看到stdlib有一些:

#[cfg(not(any(target_os = "macos", target_os = "ios", windows)]

其中涉及大量繁琐的复制和粘贴。这是唯一的方法吗?

(恐慌是坏的吗?不要这样做?这是针对build.rs脚本的, 货物)

2 个答案:

答案 0 :(得分:3)

  

其中涉及大量繁琐的复制和粘贴。这是唯一的方法吗?

根据有关条件编译的文档和RFC判断,是的,这是唯一的方法。如果有办法指定:

#[cfg(other)]
fn thing {

这将增加解析cfg属性的复杂性,因为编译器需要知道只有在未定义thingmac_os时才会编译windows

另外,这个怎么样:

#[cfg(other)]
fn thing_some_other {
  panic!("Not implemented! Please file a bug at http://... to request support for your platform")
}

#[cfg(target_os = "mac_os"]
fn thing() {
  // mac impl 
}

#[cfg(target_os = "windows"]] 
fn thing() {
  // windows impl
}

换句话说,它们需要捆绑在一起,类似于C的:

#ifdef WINDOWS
    // ...
#elif LINUX
     // ...
#else
     // ...
#endif

答案 1 :(得分:2)

没有其他办法可以做到; cfg(not(any(…, …)))是唯一的方式。

就你的“其他任何”情况而言,对于特定的构建脚本情况,运行时恐慌是可以接受的,尽管它不会出现在任何其他情况下(顺便说一句,对于这个运行时版本,有unimplemented!()可以方便存根,允许你省略信息。)

但是,我倾向于更喜欢明确的编译时失败,通常是省略它,但也可能(为了更简单地向用户指出问题是什么),你可能会包含一些在cfg条件省略它但如果不这样做会导致编译失败,如下所示:

#[cfg(not(any(target_os = "windows", target_os = "mac")))]
fn thing() {
    sorry! (this function is unimplemented for this platform, please report a bug at X)
}

在Windows和Mac上编译得很好,但是如果没有sorry宏,则不会在Linux上编译(并且提供了内容标记,它禁止像字符串和注释之外的反斜杠这样的东西)。还有其他一些更确定的方法(例如sorry = "message"没有let),但我被这个人的可爱所捕获。