返回引用、静态引用和值时出错
Error while returning reference, static reference and value
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(self) -> Path {
let values_yaml = self.0.join("helm").join("chart").join("values.yaml");
values_yaml
}
}
这是我的功能,
当 return 类型是 &Path
我得到 expected named lifetime parameter
.
当 return 类型是 &static Path
我得到 returns a reference to data owned by the current function
.
当 return 类型 Path
我得到 doesn't have a size known at compile-time
.
如何才能使该功能发挥作用?
这里的问题是 Path
类型是引用类型。它基本上指向现有的拥有 PathBuf
.
这是一个等价于 str
与 String
的关系。
此外,Path::join()
方法 return 是 PathBuf
(参见 https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.join)。
此处的解决方案是相应地更改您的 return 类型:
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(self) -> PathBuf {
let values_yaml = self.0.join("helm").join("chart").join("values.yaml");
values_yaml
}
}
Path
是一个未定大小的类型,这意味着它必须始终在像 &
或 Box
这样的指针后面使用。该类型的拥有版本为 PathBuf
。 PathBuf
实现了 Deref
到 Path
,因此您可以使用它的所有方法。这就解释了为什么你不能 return Path
.
现在为什么你不能 return &Path
从你的方法?看看 join
:Creates an owned PathBuf with path adjoined to self
。所以你在你的方法中创建了一个新的 PathBuf
和 return 对它的引用。但是一旦方法结束并且 PathBuf
超出范围,这个新的将被删除。您目前还取得了 self
的所有权,因此即使您不创建新的而只是推送到它,这也会删除 PathBuf
。
那么解决方案会是什么样子呢?假设您不想修改 Deploy
中的 PathBuf
,您只需 return 一个拥有的 PathBuf
.
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(&self) -> PathBuf {
self.0.join("helm").join("chart").join("values.yaml")
}
}
fn main() {
let s = r"/etc";
let deploy = Deploy(PathBuf::from(s));
let values_yaml = deploy.values_yaml();
i_take_a_path(&values_yaml);
}
fn i_take_a_path(path: &Path) {
println!("{:?}", path);
}
如果你真的想修改 Deploy
的基础 PathBuf
,你会这样做:
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(&mut self) -> &Path {
self.0.push("helm");
self.0.push("chart");
self.0.push("values.yaml");
self.0.as_path()
}
}
fn main() {
let s = r"/etc";
let mut deploy = Deploy(PathBuf::from(s));
let values_yaml = deploy.values_yaml();
i_take_a_path(values_yaml);
}
fn i_take_a_path(path: &Path) {
println!("{:?}", path);
}
这次引用有效,因为它直接指向 Deploy
中的 PathBuf
,而不是新创建的。
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(self) -> Path {
let values_yaml = self.0.join("helm").join("chart").join("values.yaml");
values_yaml
}
}
这是我的功能,
当 return 类型是 &Path
我得到 expected named lifetime parameter
.
当 return 类型是 &static Path
我得到 returns a reference to data owned by the current function
.
当 return 类型 Path
我得到 doesn't have a size known at compile-time
.
如何才能使该功能发挥作用?
这里的问题是 Path
类型是引用类型。它基本上指向现有的拥有 PathBuf
.
这是一个等价于 str
与 String
的关系。
此外,Path::join()
方法 return 是 PathBuf
(参见 https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.join)。
此处的解决方案是相应地更改您的 return 类型:
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(self) -> PathBuf {
let values_yaml = self.0.join("helm").join("chart").join("values.yaml");
values_yaml
}
}
Path
是一个未定大小的类型,这意味着它必须始终在像 &
或 Box
这样的指针后面使用。该类型的拥有版本为 PathBuf
。 PathBuf
实现了 Deref
到 Path
,因此您可以使用它的所有方法。这就解释了为什么你不能 return Path
.
现在为什么你不能 return &Path
从你的方法?看看 join
:Creates an owned PathBuf with path adjoined to self
。所以你在你的方法中创建了一个新的 PathBuf
和 return 对它的引用。但是一旦方法结束并且 PathBuf
超出范围,这个新的将被删除。您目前还取得了 self
的所有权,因此即使您不创建新的而只是推送到它,这也会删除 PathBuf
。
那么解决方案会是什么样子呢?假设您不想修改 Deploy
中的 PathBuf
,您只需 return 一个拥有的 PathBuf
.
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(&self) -> PathBuf {
self.0.join("helm").join("chart").join("values.yaml")
}
}
fn main() {
let s = r"/etc";
let deploy = Deploy(PathBuf::from(s));
let values_yaml = deploy.values_yaml();
i_take_a_path(&values_yaml);
}
fn i_take_a_path(path: &Path) {
println!("{:?}", path);
}
如果你真的想修改 Deploy
的基础 PathBuf
,你会这样做:
use std::path::Path;
use std::path::PathBuf;
struct Deploy(PathBuf);
impl Deploy {
fn values_yaml(&mut self) -> &Path {
self.0.push("helm");
self.0.push("chart");
self.0.push("values.yaml");
self.0.as_path()
}
}
fn main() {
let s = r"/etc";
let mut deploy = Deploy(PathBuf::from(s));
let values_yaml = deploy.values_yaml();
i_take_a_path(values_yaml);
}
fn i_take_a_path(path: &Path) {
println!("{:?}", path);
}
这次引用有效,因为它直接指向 Deploy
中的 PathBuf
,而不是新创建的。