IT评测·应用市场-qidao123.com

标题: Rust语言 - 接口设计的建议之受约束(Constrained) [打印本页]

作者: 小小小幸运    时间: 2023-6-21 09:43
标题: Rust语言 - 接口设计的建议之受约束(Constrained)
Rust语言 - 接口设计的建议之受约束(Constrained)

受约束(Constrained)

接口的更改要三思

向后不兼容的修改

类型修改

例子一:
  1. pub mod outer_mod {
  2.   pub mod inner_mod {
  3.     // This function is visible within `outer_mod`
  4.     pub(in crate::outer_mod) fn outer_mod_visible_fn() {}
  5.    
  6.     // This function is visible to the entire crate
  7.     pub(crate) fn crate_visible_fn() {}
  8.    
  9.     // This function is visible within `outer_mod`
  10.     pub(super) fn super_mod_visible_fn() {
  11.       // This function is visible since we're in the same `mod`
  12.       inner_mod_visible_fn();
  13.     }
  14.    
  15.     // This function is visible only within `inner_mod`,
  16.     // which is the same as leaving it private.
  17.     pub(self) fn inner_mod_visible_fn() {}
  18.   }
  19.   
  20.   pub fn foo() {
  21.     inner_mod::outer_mod_visible_fn();
  22.     inner_mod::crate_visible_fn();
  23.     inner_mod::super_mod_visible_fn();
  24.    
  25.     // This function is no longer visible since we're outside of `inner_mod`
  26.     // Error! `inner_mod_visible_fn` is private
  27.     // inner_mod::inner_mod_visible_fn();
  28.   }
  29. }
  30. fn bar() {
  31.   // This function is still visible since we're in the same crate
  32.   outer_mod::inner_mod::crate_visible_fn();
  33.   
  34.   // This function is no longer visible since we're outside of `outer_mod`
  35.   // Error! `super_mod_visible_fn` is private
  36.   outer_mod::inner_mod::super_mod_visible_fn();
  37.   
  38.   // This function is no longer visible since we're outside of `outer_mod`
  39.   // Error! `outer_mod_visible_fn` is private
  40.   outer_mod::inner_mod::outer_mod_visible_fn();
  41.   
  42.   outer_mod::foo();
  43. }
  44. fn main() {
  45.   bar()
  46. }
复制代码
例子二:
lib.rs
  1. pub struct Unit;
复制代码
main.rs
  1. fn main() {
  2.   let u = constrained::Unit; // v0 库是 constrained
  3. }
复制代码
修改一
lib.rs
  1. pub struct Unit {
  2.   pub field: bool,
  3. }
复制代码
main.rs
  1. fn is_true(u: constrained::Unit) -> bool {
  2.   matches!(u, constrained::Unit { field: true })
  3. }
  4. fn main() {
  5.   let u = constrained::Unit; // v0  报错,因为添加字段之后 Unit struct 原有的构造方式不可用
  6. }
复制代码
修改二
lib.rs
  1. pub struct Unit {
  2.   local: i32, // 增加私有字段
  3. }
复制代码
main.rs
  1. fn main() {
  2.   let u = constrained::Unit; // v0  报错,虽然字段看不见,但是编译器可以看到
  3. }
复制代码
例子三:
lib.rs
  1. #[non_exhaustive]
  2. pub struct Config {
  3.   pub window_width: u16,
  4.   pub window_height: u16,
  5. }
  6. fn SomeFunction() {
  7.   let config = Config {
  8.     window_width: 640,
  9.     window_height: 480,
  10.   };
  11.   
  12.   // Non-exhaustive structs can be matched on exhaustively within the defining crate.
  13.   if let Config {
  14.     window_width,
  15.     window_height,
  16.   } = config
  17.   {
  18.     // ...
  19.   }
  20. }
复制代码
main.rs
  1. use constrained::Config;
  2. fn main() {
  3.   // Not allowed.
  4.   let config =  Config {  // 报错
  5.     window_width: 640,
  6.     window_height: 480,
  7.   };
  8.   
  9.   if let Config {
  10.     window_width,
  11.     window_height,
  12.     .. // This is the only difference. 必须加 .. 否则报错
  13.   } = config
  14.   {
  15.     // ...
  16.   }
  17. }
复制代码
Trait 实现

例子四:
lib.rs
  1. pub struct Unit;
  2. pub trait Fool {
  3.   fn foo(&self);
  4. }
复制代码
main.rs
  1. use constrained::{Foo1, Unit};
  2. trait Foo2 {
  3.   fn foo(&self);
  4. }
  5. impl Foo2 for Unit {
  6.   fn foo(&self) {
  7.     println!("foo2");
  8.   }
  9. }
  10. fn main() {
  11.   Unit.foo()
  12. }
复制代码
修改一
lib.rs
  1. pub struct Unit;
  2. pub trait Fool {
  3.   fn foo(&self);
  4. }// case 1: Add impl Foo1 for Unit in this crateimpl Foo1 for Unit {  fn foo(&self) {    println!("foo1");  }}
复制代码
main.rs
  1. use constrained::{Foo1, Unit};
  2. trait Foo2 {
  3.   fn foo(&self);
  4. }
  5. impl Foo2 for Unit {
  6.   fn foo(&self) {
  7.     println!("foo2");
  8.   }
  9. }
  10. fn main() {
  11.   Unit.foo() // 报错
  12. }
复制代码
修改二
lib.rs
  1. pub struct Unit;
  2. pub trait Fool {
  3.   fn foo(&self);
  4. }// case 2: Add a new public Traitpub trait Bar1 {  fn foo(&self); // with the same name}impl Bar1 for Unit {  fn foo(&self) {    println!("bar1");  }}
复制代码
main.rs
  1. use constrained::{Foo1, Unit};
  2. trait Foo2 {
  3.   fn foo(&self);
  4. }
  5. impl Foo2 for Unit {
  6.   fn foo(&self) {
  7.     println!("foo2");
  8.   }
  9. }
  10. fn main() {
  11.   Unit.foo()  // 因为没有引入lib.rs中的Bar1,所以暂时没有报错
  12. }
复制代码
main.rs
  1. use constrained::*;
  2. trait Foo2 {
  3.   fn foo(&self);
  4. }
  5. impl Foo2 for Unit {
  6.   fn foo(&self) {
  7.     println!("foo2");
  8.   }
  9. }
  10. fn main() {
  11.   Unit.foo()  // 报错
  12. }
复制代码
例子五:
lib.rs
  1. use std::fmt::{Debug, Display};
  2. mod sealed {
  3.   use std::fmt::{Debug, Display};
  4.   
  5.   pug trait Sealed {}
  6.   impl<T> Sealed for T where T: Debug + Display {}
  7. }
  8. pub trait CanUseCannotImplement: sealed::Sealed {
  9.   // ..
  10. }
  11. impl<T> CanUseCannotImplement for T where T: Debug + Display {}
复制代码
main.rs
  1. use std::fmt::{Debug, Display};
  2. use constrained::CanUseCannotImplement;
  3. pub struct Bar {}
  4. impl Debug for Bar {
  5.   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  6.     Ok(())
  7.   }
  8. }
  9. impl Display for Bar {
  10.   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  11.     Ok(())
  12.   }
  13. }
  14. // impl CanUseCannotImplement for Bar {}  // 报错 因为在 lib.rs 中已经实现好了,不能再实现
  15. // Conflicting implementation,
  16. // The trait `CanUseCannotImplement` has been already implemented
  17. // for the types that satisfy the bounds specified by the sealed trait which are `Debug + Display`
  18. pub struct Foo {}
  19. impl CanUseCannotImplement for Foo {} // 报错 没有实现 Debug 和 Display
  20. fn main() {}
复制代码
隐藏的契约

隐藏的契约 - 重新导出(Re-Exports)

例子六:
lib.rs
  1. // 你的 crate,叫 bestiter
  2. pub fn iter<T>() -> itercrate::Empty<T> { .. }
  3. // 依赖的外部 crate,叫 itercrate (v1.0),提供了 Empty<T> 类型
  4. // 用户的 crate 中
  5. struct EmptyIterator { it: itercrate::Empty<()> }
  6. EmptyIterator { it: bestiter::iter() }
  7. // ---------------------------------------------------------------
  8. // 你的 crate, 叫 bestiter
  9. pub fn iter<T>() -> itercrate::Empty<T> { .. }
  10. // 依赖的外部crate,叫 itercrate,提供了 Empty<T> 类型
  11. // 依赖的版本改为 v2.0,别处没有更改
  12. // 编译器认为:itercrate1.0::Empty 和 itercrate2.0::Empty 是不同的类型
  13. // 导致破坏性变更
  14. // 用户的 crate 中
  15. struct EmptyIterator { it: itercrate::Empty<()> }
复制代码
隐藏的契约 - 自动 Trait(Auto-Traits)

例子七:
  1. fn is_normal<T: Sized + Send + Sync + Unpin>() {}
  2. #[test]
  3. fn normal_types() {
  4.   is_normal::<MyType>();
  5. }
复制代码
设计 Rust 接口的总结


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4