我正在为C库编写一个包装器/ FFI,它需要在主线程中进行全局初始化调用以及一个用于销毁的调用.
以下是我目前处理它的方式:
struct App;
impl App {
fn init() -> Self {
unsafe { ffi::InitializeMyCLib(); }
App
}
}
impl Drop for App {
fn drop(&mut self) {
unsafe { ffi::DestroyMyCLib(); }
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用如下:
fn main() {
let _init_ = App::init();
// ...
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但感觉就像一个黑客,将这些调用绑定到不必要的结构的生命周期.在finally(Java)或at_exit(Ruby)块中使用析构函数似乎在理论上更合适.
在Rust中有更优雅的方法吗?
编辑
是否可以/安全地使用此设置(使用lazy_static包),而不是上面的第二个块:
lazy_static! {
static ref APP: App = App::new();
}
Run Code Online (Sandbox Code Playgroud)
是否可以保证在任何其他代码之前初始化此引用并在退出时销毁?lazy_static在图书馆使用是不好的做法?
这也可以通过这个结构更方便地访问FFI,因为我不必费心地传递对实例化结构的引用(_init_在我的原始示例中调用).
这也会使它在某些方面更安全,因为我可以将Appstruct默认构造函数设为私有.
除非请求dataType设置为"jsonp"或"script",否则不会在IE9中执行跨域AJAX请求(使用jQuery 1.7.2创建).
我在构建请求时发现了这个问题,我不关心响应,并且未指定dataType(是的,我知道我应该关心响应).
所以,例如,这将工作:
$.ajax({
url: "http://www.google.com",
type: "GET", // or "POST"
dataType: 'jsonp'
});
Run Code Online (Sandbox Code Playgroud)
但这不会:
$.ajax({
url: "http://www.google.com",
type: "GET" // or "POST"
});
Run Code Online (Sandbox Code Playgroud)
通过"工作"我的意思是我看到在Firebug或F12中发出的HTTP请求.
这两个请求都适用于其他浏览器 设置jQuery.support.cors = true;不会影响成功,也不会将crossDomain设置为true,也不会将cache设置为false(在AJAX请求中).
为什么AJAX请求的成功取决于IE中请求的dataType?我能理解为什么它会影响我处理任何返回数据的能力; 我也理解一些服务器可能会拒绝对某个dataType的所有请求(但这显然不是这种情况).
我有一个看起来像这样的函数:
type Attributes = HashMap<String, json::Json>;
type Store = Arc<RwLock<HashMap<String, RwLock<Attributes>>>>;
fn get(store: &Store, key: &str) -> Option<Attributes> {
store.read().iter()
.filter_map(|g| (*g).get(key) )
.filter_map(|v| v.read().ok() )
.map(|v| (*v).clone() )
.next()
}
Run Code Online (Sandbox Code Playgroud)
这编译并且工作得很好.但是,对于我自己的启发,我一直在尝试修改它以使用标准Result/ Option方法(不转换LockResult为a Iter),类似于:
store.read().ok()
.and_then(|g| (*g).get(key) )
.and_then(|v| v.read().ok() )
.map(|v| (*v).clone() );
Run Code Online (Sandbox Code Playgroud)
但这告诉我g does not live long enough.我试着加入ref和as_ref在不同的地方,但不能让它编译.我错过了什么?
我知道我可以像以下一样工作:
store.read().ok()
.and_then(|g| {
(*g).get(key)
.and_then(|v| v.read().ok() )
.map(|v| (*v).clone() )
})
Run Code Online (Sandbox Code Playgroud)
但我希望能够像在iter案件中一样链接它.
store_accessor在 Rails 5 中,是否可以将新的属性 API 与通过列公开的字段一起使用jsonb?
例如,我有:
class Item < ApplicationRecord
# ...
store_accessor :metadata, :publication_date
attribute :publication_date, :datetime
end
Run Code Online (Sandbox Code Playgroud)
然后我想打电话给i = Item.new(publication_date: '2012-10-24'),并得到metadata一个像这样的哈希值:{ 'publication_date' => #<DateTimeInstance> }。
不过,这个attribute电话似乎并没有任何强制作用。
希望我遗漏了一些东西——在使用列时,能够结合使用这两个功能似乎非常有用jsonb。(说到这里,为什么属性 API 不公开通用array: true选项?这对于这种情况也非常有用。)
如果 RustOption提供了一些额外的便利方法,比如Option#flattenand Option#flat_map,那么这将是很好的, whereflatten会将 an 减少<Option<Option<T>>到Option<T>,并且flat_map会像 一样工作map,但采用返回 anOption并将其展平的方法/闭包。
flat_map 非常简单:
fn opt_flat_map< T, U, F: FnOnce(T) -> Option<U> >(opt: Option<T>, f: F) -> Option<U> {
match opt {
Some(x) => f(x),
None => None
}
}
Run Code Online (Sandbox Code Playgroud)
flatten更复杂,我真的不知道如何定义它。它可能看起来像:
fn opt_flatten<T, U>(opt: Option<T>) -> Option<U> {
match opt {
Some( Some(x) ) => flatten_option( Some(x) ),
_ => opt
}
}
Run Code Online (Sandbox Code Playgroud)
但这肯定行不通。有什么想法吗?
另外,我将如何在Option …
为什么这段代码会编译?
#[derive(Debug)]
pub struct Foo<'a> {
pub x: &'a [&'a str],
}
fn main() {
let s = "s".to_string();
let t: &str = s.as_ref();
{
let v = vec![t];
let foo = Foo { x: &v[..] };
println!("{:?}", &foo);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的Foo结构中,我的x字段包含一片&strs.我对这些生命周期标签的理解是切片和个体&strs具有相同的寿命.
但是,在我的示例中,&str t(在外部块中)与容器切片(在内部块中)的生命周期不同.