mirror of
https://github.com/darkicewolf50/RustBrock.git
synced 2025-07-06 11:07:12 -06:00
ch6.1 started
This commit is contained in:
155
data_types.md
155
data_types.md
@ -609,4 +609,157 @@ ex
|
||||
```
|
||||
|
||||
you have have multiple impl blocks associated with a struct, is the same as hvaing one monolithic one (better for readibility)
|
||||
some use cases for multiple impl blocks
|
||||
some use cases for multiple impl blocks
|
||||
|
||||
# Enums
|
||||
allows for defining a type determined by its possible variants
|
||||
can only be one variant at a time
|
||||
|
||||
definition
|
||||
```rust
|
||||
enum IpAddrKind {
|
||||
V4, // possible variant value
|
||||
V6, // possible variant value
|
||||
}
|
||||
```
|
||||
|
||||
initiation/storing enum value
|
||||
```rust
|
||||
let six = IpAddrKind::V6;
|
||||
let four = IpAddrKind::V4;
|
||||
```
|
||||
|
||||
these need to be namespaced using the :: operator in order to tell the compiler which value you mean
|
||||
|
||||
other useage
|
||||
```rust
|
||||
fn route (ip_kind: IpAddrKind) {}
|
||||
|
||||
// can be called by using either varaint
|
||||
route(IpAddrKind::V4);
|
||||
route(IpAddrKind::V6);
|
||||
```
|
||||
|
||||
we only know the kind of addr using the enum, to store the value can be done by using a struct
|
||||
ex
|
||||
|
||||
```rust
|
||||
struct IpAddr {
|
||||
kind: IpAddrKind,
|
||||
address: String,
|
||||
}
|
||||
|
||||
let homeIp = IpAddr {
|
||||
kind: IpAddrKind::V4,
|
||||
address: String::from("127.0.0.1"),
|
||||
};
|
||||
|
||||
let loopback = IpAddr {
|
||||
kind: IpAddrKind::V6,
|
||||
address: String::from("::1"),
|
||||
}
|
||||
```
|
||||
|
||||
now each type of ip addr as an assocatiated value
|
||||
|
||||
with just an enum and no struct, where the values are directly attached
|
||||
this is more concise but communicates the same thing
|
||||
|
||||
```rust
|
||||
enum IpAddr {
|
||||
V4(String),
|
||||
V6(String),
|
||||
}
|
||||
|
||||
let homeIp = IpAddr::V4(String::from("127.0.0.1"));
|
||||
|
||||
let loopback = IpAddr::V6(String::from("::1"));
|
||||
```
|
||||
|
||||
enums can have different types from another
|
||||
ipv4 will always have 4 different values from 0-255
|
||||
```rust
|
||||
enum IpAddr {
|
||||
V4(u8, u8, u8, u8),
|
||||
V6(String),
|
||||
}
|
||||
|
||||
let homeIp = IpAddr::V4(127, 0, 0, 1);
|
||||
|
||||
let loopback = IpAddr::V6(String::from("::1"));
|
||||
```
|
||||
|
||||
This encoding and differentiating of Ip adresses is so common that the standard library has an enum named IpAddr, this needs to be brought into scope in order to work
|
||||
|
||||
This stores two structs for V4 and V6
|
||||
|
||||
like this
|
||||
```rust
|
||||
struct Ipv4Addr {
|
||||
// --snip--
|
||||
}
|
||||
|
||||
struct Ipv6Addr {
|
||||
// --snip--
|
||||
}
|
||||
|
||||
enum IpAddr {
|
||||
V4(Ipv4Addr),
|
||||
V6(Ipv6Addr),
|
||||
}
|
||||
```
|
||||
|
||||
can put anything in a enum and enums can have unlimited types assocaited with them
|
||||
|
||||
could be nothing, i32, string, tuple for example
|
||||
|
||||
can implement behavior in relation to an enum
|
||||
|
||||
## The Option Enum and Advantages over Null types
|
||||
|
||||
this is a specail case where the variants are nothing nas something
|
||||
this is part of the standard library can can be included
|
||||
|
||||
this should be handled so that the compiler can check for handling all types
|
||||
this then handle the case of what if it is empty
|
||||
|
||||
a feature of rust is excluding null references
|
||||
|
||||
if you try to use a null value as a not null value you get an error
|
||||
this is due to null or not null as pervasive and extrememly easy to make this kind of error
|
||||
|
||||
null is still useful for expressing a vlaue that is not present or not valid for some reason
|
||||
this is a problem of implementation
|
||||
|
||||
rust doesnt have nulls but can be expressed as the enum Option<T>
|
||||
which is defined by the standard library as
|
||||
```rust
|
||||
enum Option<T> {
|
||||
None,
|
||||
Some(T),
|
||||
}
|
||||
```
|
||||
|
||||
dont need to explicitly bring into scope but can
|
||||
can also call it by ``Some`` or ``None``
|
||||
<T> is the genertic type parameter
|
||||
all of these replace the T generic tpye in the Option enum
|
||||
|
||||
```rust
|
||||
let some_number = Some(5); // can be inferred due to the value being stored
|
||||
let some_char = Some('e'); // can be inferred due to the value being stored
|
||||
|
||||
let absent_number: Option<i32> = None; // needs generic type sepcification for the None option
|
||||
```
|
||||
|
||||
all valid T is any type
|
||||
|
||||
these are not the same and therefore cannot be added
|
||||
i8 and Option<i8>
|
||||
|
||||
the compiler will always ensure that i8 is a valid value
|
||||
the complier will not ensure that Option<i8> stores a valid value
|
||||
will have to check if it has a non-null value in the enum then convert it into a T type from Option<T> type in order to use it
|
||||
|
||||
this eliminates the issue of it being assued that is it a non-null tpye by being forced to handle the null variant
|
||||
everywhere where the value isnt a Option<T> can be safely assumed to be a non null type
|
||||
|
Reference in New Issue
Block a user