Rust Standard Library Cookbook by Jan Nils Ferner

Rust Standard Library Cookbook by Jan Nils Ferner

Author:Jan Nils Ferner
Language: eng
Format: mobi, epub
Tags: COM051440 - COMPUTERS / Software Development and Engineering / Tools, COM051010 - COMPUTERS / Programming Languages / General, COM043000 - COMPUTERS / Networking / General
Publisher: Packt
Published: 2018-03-29T09:23:16+00:00


Boxing data

The first smart pointer we are going to look at is the Box. This very special type is the analogue to C++'s unique_ptr, a pointer to data stored on the heap that deletes said data automatically when it's out of scope. Because of the shift from stack to heap, Box can allow you some flexibility by intentionally losing type information.

How to do it...

In the bin folder, create a file called boxing.rs.

Add the following code and run it with cargo run --bin boxing:

1 use std::fs::File;

2 use std::io::BufReader;

3 use std::result::Result;

4 use std::error::Error;

5 use std::io::Read;

6 use std::fmt::Debug;

7

8 #[derive(Debug)]

9 struct Node<T> {

10 data: T,

11 child_nodes: Option<(BoxedNode<T>, BoxedNode<T>)>,

12 }

13 type BoxedNode<T> = Box<Node<T>>;

14

15 impl<T> Node<T> {

16 fn new(data: T) -> Self {

17 Node {

18 data,

19 child_nodes: None,

20 }

21 }

22

23 fn is_leaf(&self) -> bool {

24 self.child_nodes.is_none()

25 }

26

27 fn add_child_nodes(&mut self, a: Node<T>, b: Node<T>) {

28 assert!(

29 self.is_leaf(),

30 "Tried to add child_nodes to a node that is not a leaf"

31 );

32 self.child_nodes = Some((Box::new(a), Box::new(b)));

33 }

34 }

35

36 // Boxes enable you to use traditional OOP polymorph

37 trait Animal: Debug {

38 fn sound(&self) -> &'static str;

39 }

40

41 #[derive(Debug)]

42 struct Dog;

43 impl Animal for Dog {

44 fn sound(&self) -> &'static str {

45 "Woof!"

46 }

47 }

48

49 #[derive(Debug)]

50 struct Cat;

51 impl Animal for Cat {

52 fn sound(&self) -> &'static str {

53 "Meow!"

54 }

55 }

56

57 fn main() {

58 let mut root = Node::new(12);

59 root.add_child_nodes(Node::new(3), Node::new(-24));

60 root.child_nodes

61 .as_mut()

62 .unwrap()

63 0

64 .add_child_nodes(Node::new(0), Node::new(1803));

65 println!("Our binary tree looks like this: {:?}", root);

66

67 // Polymorphism

68 let mut zoo: Vec<Box<Animal>> = Vec::new();

69 zoo.push(Box::new(Dog {}));

70 zoo.push(Box::new(Cat {}));

71 for animal in zoo {

72 println!("{:?} says {}", animal, animal.sound());

73 }

74

75 for word in caps_words_iter("do you feel lucky, punk‽") {

76 println!("{}", word);

77 }

78

79 // Assuming a file called number.txt exists

80 let num = read_file_as_number("number.txt").expect("Failed

read the file as a number");

81 println!("number.txt contains the number {}", num);

82

83 // Dynamically composing functions

84 let multiplier = create_multiplier(23);

85 let result = multiplier(3);

86 println!("23 * 3 = {}", result);

87 }

88

89 // Via trait objects we can return any iterator

90 fn caps_words_iter<'a>(text: &'a str) -> Box<Iterator<Item =

String> + 'a> {

91 // Return an iterator over every word converted into

ALL_CAPS

92 Box::new(text.trim().split(' ').map(|word|

word.to_uppercase()))

93 }

94

95 // Same goes for errors

96 fn read_file_as_number(filename: &str) -> Result<i32,

Box<Error>> {

97 let file = File::open(filename)?;

98 let mut buf_reader = BufReader::new(file);

99 let mut content = String::new();

100 buf_reader.read_to_string(&mut content)?;

101 let number: i32 = content.parse()?;

102 Ok(number)

103 }

104

105 fn create_multiplier(a: i32) -> Box<Fn(i32) -> i32> {

106 Box::new(move |b| a * b)

107 }



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.