本Akatsuki飞船拍摄到的金星阴面热红外发光现象。
2017年,英国科学家领导的研究团队使用詹姆斯·克拉克·麦克斯韦望远镜(JCMT),在266.94千兆赫下发现了金星无线电的一个特征信号。磷化氢和二氧化硫都会吸收这个频率附近的无线电波。为了弄清楚究竟是哪种化合物“捣的鬼”,该团队在2019年用阿塔卡玛大型毫米/亚毫米阵列(ALMA)进行了后续观测。最终,他们得出结论:金星的二氧化硫水平太低,无法解释特征信号,因此,信号来自磷化氢。这令许多研究人员感到非常惊讶:地球大气中含有的少量磷化氢是由生命产生的,难道被称为“地狱之景”的金星,也以某种未知方式庇护了酸性云层中的生命?
此后,很多科学团队对该探测结果的可靠性提出了质疑。phys.org网站当地时间1月27日报道,美国华盛顿大学领导的团队利用金星大气的可靠辐射传输模型,重新考察并全面解释了射电望远镜观测结果。相关论文可在arXiv预印网站中查询。
研究人员模拟了不同层级金星大气的磷化氢和二氧化硫信号,以及这些信号在JCMT和ALMA当时设置条件下的接收情况。研究人员指出,被认定为“磷化氢”信号特征显示,吸收物质并非来自金星云层,而是来自金星云层中层,距地表50公里以上的区域——这里高浓度的化学物质和强烈的紫外线辐射,短短几秒内就会撕碎磷化氢分子。
天文学教授Victoria Meadows说:“二氧化硫是金星大气中第三常见的化合物,它与生命迹象无关。中间大气层的磷化氢甚至比金星云层中的磷化氢更脆弱。如果JCMT信号来自中间层,磷化氢必须以100倍于光合作用氧气注入地球大气的速度,输入中间层。”考虑到信号强度、金星的二氧化硫水平以及金星大气的恶劣化学环境(硫酸云),英国研究小组很可能根本没有探测到磷化氢,此前的特征信号来自二氧化硫。
研究人员还发现,ALMA的数据很可能严重低估了金星大气中的二氧化硫含量,而这也是此前英国团队误判“磷化氢”信号的原因之一。论文作者、喷气推进实验室研究员Alex Akins说:“ALMA在2019年的天线配置条件会导致谱线稀释现象——金星大气中的常见气体(如二氧化硫)释放出的信号比更小范围分布气体释放的信号更弱,这种现象最终造成JCMT的二氧化硫观测值偏低。”
研究人员表示,全球科学家的最新观测结果为金星的生命之谜提供了另一种解释。剧毒的大气、惊人的高压及高温,地狱般的金星对人类来说仍然是一个神秘的星球,还有很多谜团有待解决。
原创编译:雷鑫宇 审稿:西莫 责编:陈之涵
期刊来源:《天体物理学杂志》、《自然·天文学》
期刊编号:0004-637X,2397-3366
原文链接:https://phys.org/news/2021-01-purported-phosphine-venus-ordinary-sulfur.html
版权声明:本文为原创编译,中文内容仅供参考,一切内容以英文原版为准。转载请注明来源。
TML 规范的开发是一个渐进的过程,有时会出现问题。随着时间的推移,许多元素和属性被添加到 HTML 中,直到后来 Web 社区集体意识到有更好的方法时才被删除。由于已弃用和过时的元素和属性已经存在于网络上,因此许多现代浏览器继续支持它们的使用。尽管它们可能仍然有效,但您应该始终遵循最新版本的要求 HTML。不能保证浏览器对过时和弃用元素的支持会持续下去。有效但执行不A力。
有几种 HTML 元素和属性是有效的并且应该被使用,但是这些特性的实现随着时间的推移而发生了变化,而 Web 开发社区的一些人还没有注意到。HTMLtables就是一个很好的例子。table在某一时刻,使用 HTML元素创建网页布局是很常见的。几乎没有人再这样做了,CSS 比tables以往任何时候都更强大。但是,即使是经验丰富的 Web 开发人员,也存在许多其他不太严重的误用和语法错误。以下是一些经常被误用得完全有效且有用的 HTML 功能以及正确实现的示例。
虽然在技术上不是 HTML 元素,但DOCTYPE声明应该是每个 HTML 文档中出现的第一件事。这个声明是浏览器文档中代码的语言。过去,这个声明包括几个部分,可能会有点复杂。然而,在 HTML5 中,这很简单:
使用该声明开始每个人 HTML 文档,Web 浏览器将准确地知道您要说什么。
Web 浏览器必须知道用于编写文档的字符集才能正确呈现它。在绝大多数情况下,要声明的正确字符集是UTF-8。如果您需要声明其他任何内容,很可能您已经知道并知道如何去做。如果您不确定,请坚持使用 UTF-8 是一个安全的选择。在 HTML5 中声明字符集比在以前的 HTML 版本中要简单得多。这是现代 HTML5 中声明的正确语法:
只需将该行放到head您的 HTML 文档中即可。
过去,通常使用meta标签来提供版权信息。但是,这不是处理此任务的正确方法,并且网络爬虫无法识别标签的这种标签外使用meta。识别版权的正确方法是使用HTML 文档link中的元素,如下所示:head
您还可以在锚点和区域元素上使用rel="license"属性值对。
在过去,通常使用如下语法将脚本添加到 HTML 文档中:
这是有充分理由的。在某一时刻,许多浏览器无法识别script标签,并试图将标签之间的内容呈现为 HTML,从而导致它们以纯文本形式显示脚本。为了避免这个问题,开发人员会注释掉文本,这样它就不会被不受支持的浏览器呈现为 HTML。那些日子已经离我们很远了。所有现代浏览器都支持该script标签。只需完全删除 HTML 注释括号,或者更好的是,将 JavaScript 编写在单独的文件中,然后使用script标记将其导入到当前的 HTML 文档中,如下所示:
还有不少元素曾经是 HTML 规范的一部分,但后来被弃用或废弃。以下是您可能仍在使用的八个 HTML 元素,您应该立即停止使用它们以及您可以使用的替代标签:
有许多元素和属性曾经是 HTML 的一部分,但执行的任务更适合 CSS。这些元素已经被弃用,取而代之的是让 CSS 控制网页呈现。
曾经使用 HTML 元素(如font、basefont、center、strike和u. 这些元素都已被弃用,取而代之的是 CSS 提供的字体和排版控件。要了解更多信息,请查看我们的字体和网页排版教程。一个从未真正流行起来的独特标签是multicol。此标签可用于将文本分成多列,类似于报纸的外观。现在可以使用 CSScolumns属性在现代浏览器中创建类似但更强大的效果。
广泛的 HTML 元素属性曾经可用于控制 HTML 元素的呈现。几乎所有这些标签都已被弃用,现在 CSS 提供了相同的功能。如果您不熟悉 CSS 以及如何实现这些属性,我们的 CSS 教程将帮助您立即开始使用层叠样式表。下面是一些更常用的属性和现在可以用来实现相同结果的 CSS 属性。
在本文中,我们介绍了一些最常见的元素和属性,这些元素和属性使用不当或已被弃用或过时。然而,我们真的只是触及了冰山一角。如果您想了解已从 HTML 规范中删除的所有 HTML 元素和属性,请参阅以下资源:
者 | Jackyzhe
责编 | 屠敏
出品 | CSDN(ID:CSDNnews)
随着我们的坑越来越多,越来越大,我们必须要对各种坑进行管理了。Rust为我们提供了一套坑务管理系统,方便大家有条不紊的寻找、管理、填埋自己的各种坑。
Rust提供给我们一些管理代码的特性:
Packages:Cargo的一个特性,帮助你进行构建、测试和共享crates
Crates:生成库或可执行文件的模块树
Modules 和use:用于控制代码组织、范围和隐私路径
Paths:struct、function和module的命名方法
下面我们来具体看一下这些特性是如何帮助我们组织代码的。
Packages和Crates
package可以理解为一个项目,而crate可以理解为一个代码库。crate可以供多个项目使用。那我们的项目中package和crate是怎么定义的呢?
之前我们总是通过IDEA来新建项目,今天我们换个方法,在命令行中使用cargo命令来创建。
$ cargo new hello-world
Created binary (application) `hello-world` package
$ ls hello-world
Cargo.toml
src
$ ls hello-world/src
main.rs
可以看到,我们使用cargo创建项目后,只有两个文件,Cargo.toml和src目录下的main.rs。
Cargo.toml是管理项目依赖的文件,每个Cargo.toml定义一个package。main.rs文件的存在表示package中包含一个二进制crate,它是二进制crate的入口文件,crate的名称和package相同。如果src目录下存在lib.rs文件,说明package中包含一个和package名称相同的库crate。
一个package可以包含多个二进制crate,它们由src/lib目录下的文件定义。如果你的项目想引用他人的crate,可以在Cargo.toml文件中增加依赖。每个crate都有自己的命名空间,因此如果你引入了一个crate里面定义了一个名为hello的函数,你仍然可以在自己的crate中再定义一个名为hello的函数。
Module
Module帮助我们在crate中组织代码,同时Module也是封装代码的重要工具。接下来还是通过一个栗子来详细了解Module。
前面我们说过,库crate定义在src/lib.rs文件中。这里首先创建一个包含了库crate的package:
cargo new --lib restaurant
然后在src中定义一些module和函数。
mod front_of_house {
mod hosting {
fn add_to_waitlist {}
fn seat_at_table {}
}
mod serving {
fn take_order {}
fn serve_order {}
fn take_payment {}
}
}
可以看到我们使用关键字mod来定义Module,Module中可以继续定义Module或函数。这样我们就可以比较方便的把相关的函数放到一个Module中,并为Module命名,提高代码的可读性。另外Module中还可以定义struct和枚举。由于Module中可以嵌套定义子Module,最终我们定义出来的代码类似一个树形。
那么如何访问Module中的函数呢?这就要提到Path了。这部分比较好理解,Module树相当于系统文件目录,而Path则是目录的路径。
Path
这里的路径和系统文件路径一样,都分为相对路径和绝对路径两种。其中绝对路径必须以crate开头,因为它代码整个Module树的根节点。路径之间使用的是双冒号来表示引用。
现在我来尝试在一个函数中调用add_to_waitlist函数:
可以看到这里不管用绝对路径还是相对路径都报错了,错误信息是模块hosting和函数add_to_waitlist是私有(private)的。我们先暂时放下这个错误,根据这里的错误提示,我们知道了当我们定义一个module时,默认情况下是私有的,我们可以通过这种方法来封装一些代码的实现细节。
OK,回到刚才的问题,那我们怎么才能解决这个错误呢?地球人都知道应该把对应的模块与函数公开出来。Rust中标识模块或函数为公有的关键字是pub。
我们用pub关键字来把对应的模块和函数公开:
这样我们就可以在module外来调用module内的函数了。
Rust中的私有规则
现在我们再回过头来看Rust中的一些私有规则,如果你试验了上面的例子,也许会有一些发现。
Rust中私有规则适用于所有项(函数、方法、结构体、枚举、模块和常量),它们默认都是私有的。父模块中的项不能访问子模块中的私有项,而子模块中的项可以访问其祖辈(父模块及以上)中的项。
Struct和Enum的私有性
Struct和Enum的私有性略有不同,对于Struct来讲,我可以只将其中的某些字段设置为公有的,其他字段可以仍然保持私有。
mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant {
// Order a breakfast in the summer with Rye toast
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
}
而对于Enum,如果一个Enum是公有的,那么它的所有值都是公有的,因为私有的值没有意义。
相对路径和绝对路径的选择
这种选择不存在正确与否,只有是否合适。因此这里我们只是举例说明一些合适的情况。
我们仍以上述代码为例,如果我们可以预见到以后需要把front_of_house模块和eat_at_restaurant函数移动到一个新的名为customer_experience的模块中,就应该使用相对路径,这样我们就对其进行调整。
类似的,如果我们需要把eat_at_restaurant函数移动到dining模块中,那么我们选择绝对路径的话就不需要做调整。
综上,我们需要对代码的优化方向有一些前瞻性,并以此来判断需要使用相对路径还是绝对路径。
相对路径除了以当前模块开头外,还可以以super开头。它表示的是父级模块,类似于文件系统中的两个点(..)。
use关键字
绝对路径和相对路径可以帮助我们找到指定的函数,但用起来也非常的麻烦,每次都要写一大长串路径。还好Rust为我们提供了use关键字。在很多语言中都有import关键字,这里的use就有些类似于import。不过Rust会提供更加丰富的用法。
use最基本的用法就是引入一个路径。我们就可以更加方便的使用这个路径下的一些方法:
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist {}
}
}
use crate::front_of_house::hosting;
pub fn eat_at_restaurant {
hosting::add_to_waitlist;
}
这个路径可以是绝对路径,也可以是相对路径,但如果是相对路径,就必须要以self开头。上面的例子可以写成:
use self::front_of_house::hosting;
这与我们前面讲的相对路径似乎有些矛盾,Rust官方说会在之后的版本处理这个问题。
use还可以更进一步,直接指向具体的函数或Struct或Enum。但习惯上我们使用函数时,use后面使用的是路径,这样可以在调用函数时知道它属于哪个模块;而在使用Struct/Enum时,则具体指向它们。当然,这只是官方建议的编程习惯,你也可以有自己的习惯,不过最好还是按照官方推荐或者是项目约定的规范比较好。
对于同一路径下的某些子模块,在引入时可以合并为一行,例如:
use std::io;
use std::cmp::Ordering;
// 等价于
use std::{cmp::Ordering, io};
有时我们还会遇到引用不同包下相同名称Struct的情况,这时有两种解决办法,一是不指定到具体的Struct,在使用时加上不同的路径;二是使用as关键字,为Struct起一个别名。
方法一:
use std::fmt;
use std::io;
fn function1 -> fmt::Result {
// --snip--
}
fn function2 -> io::Result<> {
// --snip--
}
方法二:
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1 -> Result {
// --snip--
}
fn function2 -> IoResult<> {
// --snip--
}
如果要导入某个路径下的全部模块或函数,可以使用*来表示。当然我是非常不建议使用这种方法的,因为导入全部的话,如果出现名称冲突就会很难排查问题。
对于外部的依赖包,我们需要先在Cargo.toml文件中添加依赖,然后就可以在代码中使用use来引入依赖库中的路径。Rust提供了一些标准库,即std下的库。在使用这些标准库时是不需要添加依赖的。
有些同学看到这里可能要开始抱怨了,说好了介绍怎么拆分文件,到现在还是在一个文件里玩,这不是欺骗读者嘛。
别急,这就开始拆分。
开始拆分
我们拿刚才的一段代码为例:
mod front_of_house {
mod hosting {
fn add_to_waitlist {}
fn seat_at_table {}
}
mod serving {
fn take_order {}
fn serve_order {}
fn take_payment {}
}
}
首先我们可以把front_of_house模块下的内容拆分出去,需要在src目录下新建一个front_of_house.rs文件,然后把front_of_house模块下的内容写到文件中。lib.rs文件中,只需要声明front_of_house模块即可,不需要具体的定义。声明模块时,将花括号即内容改为分号就可以了。
mod front_of_house;
然后我们可以继续拆分front_of_house模块下的hosting模块和serving模块,这时需要新建一个名为front_of_house的文件件,在该文件夹下放置要拆分的模块的同名文件,把模块定义的内容写在文件中,front_of_house.rs文件同样只保留声明即可。
拆分后的文件目录如图:
本文主要讲了Rust中Package、Crate、Module、Path的概念和用法,有了这些基础,我们后面才有可能开发一些比较大的项目。
ps:本文的代码示例均来自the book(https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html)。
版权声明:本文为 CSDN博主「Jackyzhe」的原创文章。
*请认真填写需求信息,我们会在24小时内与您取得联系。