代理对象或不同方法的设计原则
Design principle for proxy objects or different approach
主要问题:
我编写了一个 cli 应用程序来与 http 服务器通信。服务器为我提供了几个端点和这些端点下的一些功能(例如/todo/add
、/other_endpoint/del
)。对库的访问应代表这些端点(例如 master.todo.add(...)
、master.other_endpoint.del(...)
)。
我的第一个尝试是添加 Master
作为对所有端点对象的引用。
struct Todo {
m: Master
}
Master
将对象保存到所有端点
struct Master {
todo: Todo,
other_endpoint: OtherEndpoint,
server: Server,
}
Master
持有一个 server
对象来与 http 服务器通信。因此端点对象可以通过 self.master.server.communicate()
.
调用此服务器对象
但我的生锈 (y) 车撞到了 recursive type 'Master' has infinite size
。在那之后,我尝试了一个 m: &'a Master
与生命周期的所有定义。但没有成功。
我现在有两个问题:
- 我需要做什么才能让它工作?
- 是否存在另一种设计(也许是更好的设计)来完成这项工作?
编辑:
- 当我询问围绕此问题的设计时,Why are recursive struct types illegal in Rust? 没有解决问题。
正如编译器告诉您的那样,Todo
和 Master
是递归类型,因此具有无限大小,您需要
insert indirection (e.g., a Box
, Rc
, or &
) at some point
所以你基本上有三个选择:
- 在
Todo
中保留Master
作为参考
这为您的结构引入了生命周期,但应该可行:
struct Server {}
struct Todo<'a> {
m: &'a Master<'a>
}
struct Master<'a> {
todo: Todo<'a>,
server: Server,
}
box
master
看起来更简单,而且您不会 运行 从一开始就陷入生命周期问题。不过请记住,box
有一个隐含的 'static
生命周期。您可能需要更改它。
struct Server {}
struct Todo{
m: Box<Master> // or if 'static is not what you need Box<Master + 'a>
}
struct Master {
todo: Todo,
server: Server,
}
- 编译器提供给您的最后一个选项是指向
Master
的引用计数指针
引用计数引入了一个小的 运行 时间开销。但是当你处理应该忽略不计的 http 请求时。
use std::rc::Rc;
struct Server {}
struct Todo{
m: Rc<Master>
}
struct Master {
todo: Todo,
server: Server,
}
这是您的三个基本选项。我会推荐你和他们一起玩来了解他们。
主要问题:
我编写了一个 cli 应用程序来与 http 服务器通信。服务器为我提供了几个端点和这些端点下的一些功能(例如/todo/add
、/other_endpoint/del
)。对库的访问应代表这些端点(例如 master.todo.add(...)
、master.other_endpoint.del(...)
)。
我的第一个尝试是添加 Master
作为对所有端点对象的引用。
struct Todo {
m: Master
}
Master
将对象保存到所有端点
struct Master {
todo: Todo,
other_endpoint: OtherEndpoint,
server: Server,
}
Master
持有一个 server
对象来与 http 服务器通信。因此端点对象可以通过 self.master.server.communicate()
.
但我的生锈 (y) 车撞到了 recursive type 'Master' has infinite size
。在那之后,我尝试了一个 m: &'a Master
与生命周期的所有定义。但没有成功。
我现在有两个问题:
- 我需要做什么才能让它工作?
- 是否存在另一种设计(也许是更好的设计)来完成这项工作?
编辑:
- 当我询问围绕此问题的设计时,Why are recursive struct types illegal in Rust? 没有解决问题。
正如编译器告诉您的那样,Todo
和 Master
是递归类型,因此具有无限大小,您需要
insert indirection (e.g., a
Box
,Rc
, or&
) at some point
所以你基本上有三个选择:
- 在
Todo
中保留
Master
作为参考
这为您的结构引入了生命周期,但应该可行:
struct Server {}
struct Todo<'a> {
m: &'a Master<'a>
}
struct Master<'a> {
todo: Todo<'a>,
server: Server,
}
box
master
看起来更简单,而且您不会 运行 从一开始就陷入生命周期问题。不过请记住,box
有一个隐含的 'static
生命周期。您可能需要更改它。
struct Server {}
struct Todo{
m: Box<Master> // or if 'static is not what you need Box<Master + 'a>
}
struct Master {
todo: Todo,
server: Server,
}
- 编译器提供给您的最后一个选项是指向
Master
的引用计数指针
引用计数引入了一个小的 运行 时间开销。但是当你处理应该忽略不计的 http 请求时。
use std::rc::Rc;
struct Server {}
struct Todo{
m: Rc<Master>
}
struct Master {
todo: Todo,
server: Server,
}
这是您的三个基本选项。我会推荐你和他们一起玩来了解他们。