Function 当实现结构的默认特性并使用函数初始化其成员时,这些函数是计算一次还是多次?

Function 当实现结构的默认特性并使用函数初始化其成员时,这些函数是计算一次还是多次?,function,rust,initialization,traits,Function,Rust,Initialization,Traits,我在板条箱里有以下伪代码 pub static struct connection { pub Id: i32, pub speed: i32, } impl Default for connection { fn default() -> Self { connection { Id: open_connection(), Speed: get_speed_at_init(), } } } 该板条箱被导入

我在板条箱里有以下伪代码

pub static struct connection {
  pub Id: i32,
  pub speed: i32,
}

impl Default for connection {
  fn default() -> Self {
      connection {
          Id: open_connection(),
          Speed: get_speed_at_init(),
      }
  }
}
该板条箱被导入到另一个项目中,并运行到多个工作线程中,其中每个线程在无限循环中使用导入的板条箱


现在我可以使用
self.connection.Id
对其执行网络操作了吗,或者
open\u connection()
会被多次评估,导致打开的连接太多而不是预期的一次?

多次。这可以简单地证明:

struct-struct;
结构的impl默认值{
fn default()->Self{
println!(“默认调用”);
结构
}
}
fn main(){
设s1=Struct::default();//打印“默认调用”
设s2=Struct::default();//打印“默认调用”
}


Default
特性或
Default
函数没有什么特别之处。它们与任何其他特性和任何其他函数一样工作。

如果我正确理解您的问题,您需要一个类型为
Connection
的全局可变变量,并且您想知道是否每次从不同的板条箱/线程导入变量时都会重新初始化该变量

在这种情况下,您不需要默认特征<代码>默认值不是一种特殊特征。它只在标准库中,因为它非常常见。要定义全局变量,必须直接初始化该值。您必须首先定义类型
连接

pub结构连接{
酒吧id:i32,
酒吧速度:i32,
}
然后创建全局变量。有许多方法可以创建全局可变变量,如中所述。假设
Connection
存储的不是整数,那么为了线程安全,您可能需要将全局文件包装成
Arc
,如果需要跨线程的可变性,则可能需要使用
Mutex
。您可以使用在运行时初始化变量,该变量允许您进行必要的方法调用以创建
连接

lazy\u static!{
发布静态引用连接:Arc=Arc::新建(连接{
id:打开连接(),
速度:在_init()处获取_速度_,
});
}
现在回答你的问题

否,生成新线程或从板条箱导入变量不会重新初始化静态变量。
静态
变量表示程序中的精确内存位置。所有对static的引用都引用相同的内存位置,无论它们位于相同的模块、机箱或线程中。我们可以通过在
open\u connection
中生成一个随机
id
并将全局
conn
放在一个单独的模块中来测试这一点:

pub-mod连接{
懒惰的人{
发布静态引用连接:Arc=Arc::新建(连接{
id:打开连接(),
速度:在_init()处获取_速度_,
});
}
fn打开_连接()->i32{
让mut rng=rand::thread_rng();
rng.gen()
}
}
您可以从多个模块或板条箱访问
接头

mod a{
使用板条箱::连接::连接;
pub fn do_stuff(){
println!(“来自a:{},conn.id的id);
}
}
//不同的板条箱
b型{
使用板条箱::连接::连接;
pub fn do_stuff(){
println!(“来自b:{}的id,conn.id);
}
}
和多线程:

mod c{
使用板条箱::连接::连接;
pub fn do_stuff(){
因为我在0..5{
std::thread::spawn(移动| |){
println!(“来自线程{}:{}的id”,i,conn.id);
})
.join()
.unwrap();
}
}
}
但是
id
将始终引用最初声明全局变量时生成的
id

fn main(){
a::做什么;
不同的板条箱::b::做东西();
c::dou_stuff();
}
//身份证号码:1037769551
//来自b的id:1037769551
//来自线程0的id:1037769551
//来自线程#1的id:1037769551
//来自线程#2的id:1037769551
//来自线程#3的id:1037769551
//来自线程4的id:1037769551

:不幸的是,操场上不能有多个板条箱,所以模块是我能做的最好的了。如果您仍然不确定,您可以随时在本地测试。

默认的
特性并不神奇。它声明了一个您的类型可以实现的函数,一旦调用它,它就会像其他函数一样工作。因此,是的,如果函数被多次调用,那么在您的情况下,将建立多个连接。@pretzelhammer噢,对不起。我在上面的代码中犯了一个错误。请查看编辑。这是否回答了您的问题?如果没有任何同步,多个线程如何安全地共享同一网络连接?此网络连接的类型是什么?你能给你的问题添加更多的细节和背景吗?因为现在还不清楚你在问什么。我投票以“需要细节”结束这个问题,因为在上的讨论表明你实际上是想问一些关于
静态
的问题,而这些问题本身并没有证明。提供一个函数,并就其行为提出一个具体的、可回答的问题(“函数
f
在此代码中是否被调用一次或两次?”)是一个好主意。Default()从不直接调用。它只是关于读取其成员变量。我希望在运行时定义一次常量,子机箱中的任何函数都不能只运行一次。有没有其他类似的方法来完成我想要的任务?不需要互斥,并且在目标是与竞争对手竞争的情况下增加系统调用开销。那么,如何在不使用互斥锁的情况下做到这一点呢?@user2284570对不起,我假设您想要可变性。我更新了我的答案,删除了
互斥
@user2284570,前提是
连接
与您的示例一样简单