如果变量声明为static
在函数的作用域中,则仅初始化一次并在函数调用之间保留其值.它的生命到底是什么?它的构造函数和析构函数何时被调用?
void foo()
{
static string plonk = "When will I die?";
}
Run Code Online (Sandbox Code Playgroud) 我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:
struct Thing {
count: u32,
}
struct Combined<'a>(Thing, &'a u32);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing { count: 42 };
Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)
有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:
struct Combined<'a>(Thing, &'a Thing);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing::new();
Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)
有时,我甚至没有参考该值,我得到同样的错误:
struct Combined<'a>(Parent, Child<'a>);
fn make_combined<'a>() -> Combined<'a> {
let parent = Parent::new();
let child = parent.child();
Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)
在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?
我正在阅读Rust书的生命周章,我在这个例子中看到了命名/显式生命周期:
struct Foo<'a> {
x: &'a i32,
}
fn main() {
let x; // -+ x goes into scope
// |
{ // |
let y = &5; // ---+ y goes into scope
let f = Foo { x: y }; // ---+ f goes into scope
x = &f.x; // | | error here
} // ---+ f and y go out of scope
// |
println!("{}", x); // |
} // -+ x goes out …
Run Code Online (Sandbox Code Playgroud) 以下函数返回的指针不会无法访问吗?
char *foo( int rc )
{
switch (rc)
{
case 1: return("one");
case 2: return("two");
default: return("whatever");
}
}
Run Code Online (Sandbox Code Playgroud)
所以C/C++中局部变量的生命周期实际上只在函数内,对吧?这意味着,在char* foo(int)
终止后,它返回的指针不再意味着什么?
我对本地var的生命周期有点困惑.谁能给我一个很好的澄清?
免责声明:我知道这是一个糟糕的设计,我只是出于好奇而问这个问题,以便尝试深入了解析构函数在C++中是如何工作的.
在C#中,可以编写:GC.KeepAlive(this)
在类的析构函数中(参见下面的编辑),这意味着即使在析构函数调用完成后,该对象仍将在内存中存活.
C++的设计是否允许从析构函数中恢复一个类似于上述C#算法的对象?
编辑:正如下面的答案所指出的,GC.ReRegisterForFinalize()
与问题的关系更为密切GC.KeepAlive(this)
.
偶尔我发现自己想要编写可以通过以下两种方式之一调用的函数:
// With a string literal:
let lines = read_file_lines("data.txt");
// With a string pointer:
let file_name = ~"data.txt";
let lines = read_file_lines(file_name);
Run Code Online (Sandbox Code Playgroud)
我的第一个猜测是使用借用的指针(&str
)作为参数类型,但是当它不起作用时(它只允许我使用@str
和~str
),我尝试了以下(通过复制Rust库),这确实有效.
fn read_file_lines<'a>(path: &'a str) -> ~[~str] {
let read_result = file_reader(~Path(path));
match read_result {
Ok(file) => file.read_lines(),
Err(e) => fail!(fmt!("Error reading file: %?", e))
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我不明白我在做什么.从我可以收集的内容(主要来自编译器错误),我宣布一个没有限制的生命周期,并使用它来描述path参数(意味着任何生命周期都可以作为参数传递).
所以:
&str
,类型参数和类型参数之间有什么区别&'a str
?'self
?(我正在使用Rust 0.7,如果它对答案有所影响)
几天前,我遇到了ASP.Net线程的这个问题.我希望每个Web请求都有一个单例对象.我的工作单位实际上需要这个.我想为每个Web请求实例化一个工作单元,以便身份映射在整个请求中有效.这样我就可以使用IoC透明地将我自己的IUnitOfWork注入到我的存储库类中,并且我可以使用相同的实例来查询然后更新我的实体.
由于我使用Unity,我错误地使用了PerThreadLifeTimeManager.我很快意识到ASP.Net线程模型不支持我想要实现的目标.基本上它使用theadpool并回收线程,这意味着每个线程我得到一个UnitOfWork!但是,我想要的是每个Web请求的一个工作单元.
一些谷歌搜索给了我这个伟大的帖子.这正是我想要的; 除了非常容易实现的统一部分.
这是我对PerCallContextLifeTimeManager实现统一的实现:
public class PerCallContextLifeTimeManager : LifetimeManager
{
private const string Key = "SingletonPerCallContext";
public override object GetValue()
{
return CallContext.GetData(Key);
}
public override void SetValue(object newValue)
{
CallContext.SetData(Key, newValue);
}
public override void RemoveValue()
{
}
}
Run Code Online (Sandbox Code Playgroud)
当然,我使用它来使用与此类似的代码注册我的工作单元:
unityContainer
.RegisterType<IUnitOfWork, MyDataContext>(
new PerCallContextLifeTimeManager(),
new InjectionConstructor());
Run Code Online (Sandbox Code Playgroud)
希望能节省一些时间.
以下 C++ 代码打印11.1
然后崩溃。lambda 函数似乎在构造函数内被正确调用,但后来,相同的函数不再起作用!为什么会发生这种情况?lambda 的寿命有限制吗?
#include <functional>
#include <iostream>
class LambdaStore
{
public:
LambdaStore(const std::function<void(float)>& _fn)
: fn(_fn)
{
fn(11.1f); // works
}
void ExecuteStoredLambda()
{
fn(99.9f); // crashes
}
private:
const std::function<void(float)>& fn;
};
int main()
{
LambdaStore lambdaStore([](float a) { std::cout << a << '\n'; });
lambdaStore.ExecuteStoredLambda();
}
Run Code Online (Sandbox Code Playgroud) 我是NHibernate的新手,在过早关闭会话时遇到了一些问题.我通过重用会话而不是每个事务打开一个会话来暂时解决了这个问题.但是,我的印象是,每次需要时打开会话都是会话生命周期管理的推荐方法.没有?
所以; 推荐的会话方式是什么?他们的一生应该是什么?一次会议交易?一个单一的会议来处理一切?或者是什么?
编辑:
请注意,我的应用程序体系结构是与服务器端服务通信的桌面应用程序,这是使用NHibernate + Fluent进行的所有数据库处理.(如果这有任何区别......)