mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 09:15:58 +02:00
content(archive): add new archived spotlights to website
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
**What is Julia?**
|
||||
Julia is a high-level dynamic programming language for numerical computing. It is free and open-source: under the MIT license.
|
||||
Although Julia is still in its youth (the current release is v1.2), Julia provides a lot of support for mathematical analysis and data science.
|
||||
|
||||
**How hard is Julia to learn?**
|
||||
Julia is a fairly complex language but has some very simple behaviors which are easy to pick up. It is mainly used for data science and mathematical analysis, so those complexities come with it. You must understand some mathematical principles to use the language well. Julia uses certain expressions differently from other languages as well making it a bit harder to pick up; however, it makes sense. For example, string concatenation is done with \*, and not +. Julia is heavily documented and low-level, so learning the standard syntax is easy to do by following the tutorial along with other resources.
|
||||
|
||||
**What's so great about Julia?**
|
||||
|
||||
- Multiple dispatch: providing ability to define function behavior across many combinations of argument types
|
||||
- Dynamic type system: types for documentation, optimization, and dispatch
|
||||
- Good performance, approaching that of statically-compiled languages like C
|
||||
- Built-in package manager
|
||||
- Lisp-like macros and other meta-programming facilities
|
||||
- Call Python functions: use the PyCall package
|
||||
- Call C functions directly: no wrappers or special APIs
|
||||
- Powerful shell-like capabilities for managing other processes
|
||||
- Designed for parallelism and distributed computation
|
||||
- Coroutines: lightweight "green" threading
|
||||
- User-defined types are just as fast and compact as built-ins
|
||||
- Automatic generation of efficient, specialized code for different argument types
|
||||
- Elegant and extensible conversions and promotions for numeric and other types
|
||||
- Efficient support for Unicode, including but not limited to UTF-8
|
||||
|
||||
**What platforms can Julia run on?**
|
||||
Julia can run on most popular platforms such as MacOSX, most Linux builds, Windows, and others. This is due to it compiling to a native binary. However, it does not have broad support for front-end development, but there is a library for Qt bindings.
|
||||
|
||||
**CLI**
|
||||
The Julia download comes with a CLI environment. With the CLI you can try out Julia functions and expressions in the command line. (Binary languages rarely have a CLI, so this is pretty cool)
|
||||
|
||||
**Code Examples:**
|
||||
Hello world:
|
||||
|
||||
```julia
|
||||
println("Hello world!")
|
||||
```
|
||||
|
||||
FizzBuzz:
|
||||
|
||||
```julia
|
||||
fb(x) = "Fizz" ^ (x % 3 == 0) * "Buzz" ^ (x % 5 == 0) * dec(x) ^ (x % 3 != 0 && x % 5 != 0)
|
||||
println.(map(fb, 1:100))
|
||||
```
|
||||
|
||||
This is just a small list of collection tools Julia has-
|
||||
|
||||
```julia
|
||||
sum(1:100) # sum of 1-100
|
||||
filter(isOdd, 1:10) # 1,3,5,7,9
|
||||
intersect(1:10, 5:15) # 5,6,7,8,9,10
|
||||
mean([1, 3, 5, 7]) # 4
|
||||
middle([1, 3, 5]) # 3
|
||||
```
|
||||
|
||||
**Syntax and Operation Features:**
|
||||
|
||||
Matrices in Julia are easy and fun!
|
||||
|
||||
```julia
|
||||
matrix = [1 2 3; 4 5 6] #you must have a space between elements, and a semicolon between the rows
|
||||
#=
|
||||
Creates a 2x3 matrix that looks like this:
|
||||
1 2 3
|
||||
4 5 6
|
||||
=#
|
||||
```
|
||||
|
||||
Useful matrix operations:
|
||||
`hcat()`- horizontal concatenation, it stacks 2 or more matrices horizontally.
|
||||
|
||||
```julia
|
||||
matrix = [1 2 3; 4 5 6]
|
||||
hcat(matrix, [5;5]) #remember our matrix is 2x3
|
||||
#= so now this is a 2x4 matrix.
|
||||
2 -4 -3 5
|
||||
4 -2 1 5
|
||||
You'll get an error if the matrices don't have the same number of rows. =#
|
||||
```
|
||||
|
||||
`vcat()`- vertical concatenation, this operation stacks 2 or more matrices on top of each other.
|
||||
|
||||
```julia
|
||||
matrix = [1 2 3; 4 5 6] #2x3 matrix
|
||||
vcat(matrix, [0, 0, 0])
|
||||
#= 3x3 matrix
|
||||
1 2 3
|
||||
4 5 6
|
||||
0 0 0
|
||||
Cool, right? But you'll get an error if the two matrices don't have the same number of columns. =#
|
||||
```
|
||||
|
||||
A basic `if` statement:
|
||||
|
||||
```julia
|
||||
if 5>=4
|
||||
print("Hello world")
|
||||
end
|
||||
```
|
||||
|
||||
The simplest if statements in Julia are: `if false end`, and `if true end`.
|
||||
Julia isn't whitespace sensitive, so sometimes the meaning isn't changed if you write stuff on one line.
|
||||
|
||||
While loops are pretty simple in Julia as well:
|
||||
|
||||
```julia
|
||||
while false
|
||||
print("There's nothing here.")
|
||||
end
|
||||
```
|
||||
|
||||
Ranges- There is something in Julia called a range. Ranges are written in the form `start:end`- by default, the range increments by 1. Both the start and the end of the range are inclusive (for example, `1:5` is from 1 to 5 inclusively. To explain it in interval notation, it's [1,5].)
|
||||
|
||||
```julia
|
||||
for x=1:5
|
||||
println(x)
|
||||
end
|
||||
```
|
||||
|
||||
There is a more complex form of range, written as `start:step:end`. The `end` value of the range does not have to be included. It is only included if incrementing by `step` lands on it- for example,
|
||||
|
||||
```julia
|
||||
for x=0:4:12 #12 is included because 4 is a multiple of 12
|
||||
println(x) #prints 0, 4, 8, 12
|
||||
end
|
||||
```
|
||||
|
||||
However-
|
||||
|
||||
```julia
|
||||
for x=0:4:11
|
||||
println(x) #only prints 0, 4, 8, for obvious reasons
|
||||
end
|
||||
```
|
||||
|
||||
**Resources:**
|
||||
Julia documentation: <https://docs.julialang.org>
|
||||
|
||||
Try it out online! <https://juliabox.com>, and <https://www.tutorialspoint.com/execute_julia_online.php>
|
||||
|
||||
More places to learn Julia:
|
||||
<https://julialang.org/learning/> (large collection of resources for learning Julia, from Julia)
|
||||
<https://learnxinyminutes.com/docs/julia/>
|
||||
<https://juliabyexample.helpmanual.io/>
|
||||
|
||||
Data Science in Julia:
|
||||
<https://youtu.be/SLE0vz85Rqo> (an intro to Julia for data science)
|
||||
<https://www.analyticsvidhya.com/blog/2017/10/comprehensive-tutorial-learn-data-science-julia-from-scratch/> (a walkthrough that takes you through all of the steps!)
|
||||
@@ -0,0 +1,249 @@
|
||||
**What is Redis?**
|
||||
|
||||
Redis is an in-memory datastore. It supports on-disk persistence, cache eviction, various data structures, Pub/Sub, scripting, and other features that put it in a middle ground between simple key-value store, and a more complex database.
|
||||
|
||||
**When should I use Redis?**
|
||||
|
||||
While Redis can be used in place of any persistent datastore, it's strongest when you need a speedy, easy cache. Because Redis keeps all data in memory, it's able to respond very quickly.
|
||||
|
||||
**When shouldn't I use Redis?**
|
||||
|
||||
If you need data relations, that's typically better served by a traditional SQL-based database. If you have huge amounts of data, having enough RAM to allow Redis to work with all of it may prove expensive, or prohibitive. Redis also only writes its data to disk on an interval, so if Redis is killed before it can write to disk, you may lose data between the time it was killed, and the last time it wrote to disk. (Although Redis offers different, configurable persistence strategies.)
|
||||
|
||||
**About Redis' Persistence Strategies**
|
||||
|
||||
Redis includes several persistence strategies. RDB, AOF, and AOF fsync.
|
||||
|
||||
**RDB**
|
||||
|
||||
RDB is a snapshot format, where it will provide an entire snapshot of your data at any point of time. This also is the fastest time-to-restart format for Redis with large datasets. However, because syncing the entire collection to disk is taxing on both the CPU and disk writing, it's impractical to do a full snapshot with every write. Exactly when a snapshot is produced is configurable, based on time passed, and the number of writes against the data set.
|
||||
|
||||
**AOF**
|
||||
|
||||
AOF is short for Append-Only File. This writes every command and transaction sent to Redis to a file, and reconstructs the data by replaying the file at startup. When the file becomes too large, Redis automatically creates a new one in the background by reading all in-memory data, and dumping it to a new AOF-formatted file. The cost to this is restarts with large datasets/many commands are slower than reloading a comparable RDB file, due to replaying the commands.
|
||||
|
||||
**AOF fsync**
|
||||
|
||||
AOF fsync is simply how often AOF is flushed to disk. You can use it without fsync at all, leaving it up to the operating system to flush your disk writes automatically, which depends on the operating system's configuration. You can also set it to fsync every second, meaning it will flush changes to disk every second, which is the default configuration. Finally, you can set it to flush to disk with every single write, which sacrifices speed for ensuring data is always written to disk.
|
||||
|
||||
It's not uncommon to use both RDB and AOF together to take advantage of the increased speed and durability of AOF, with the easily backed-up, quicker-to-restart RDB.
|
||||
|
||||
**Examples**
|
||||
|
||||
The simplest operation in Redis is `GET`/`SET`.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> SET some_key "Hello, Redis"
|
||||
OK
|
||||
127.0.0.1:6379> GET some_key
|
||||
"Hello, Redis"
|
||||
```
|
||||
|
||||
You can also set an expiration time on keys with `SETEX`/`PSETEX`. `SETEX` uses seconds for the expiration value, and `PSETEX` uses milliseconds.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> SETEX expiring_key 10 "Goodbye, Redis"
|
||||
OK
|
||||
127.0.0.1:6379> GET expiring_key
|
||||
"Goodbye, Redis"
|
||||
```
|
||||
|
||||
If you run the same command after ten seconds have passed, the key no longer exists.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> GET expiring_key
|
||||
(nil)
|
||||
```
|
||||
|
||||
You can set a key only if it doesn't exist (`SETNX`, `SET ... NX`) or only if it already exists. (`SET ... XX`)
|
||||
|
||||
```
|
||||
127.0.0.1:6379> SETNX existing_key "This key was free."
|
||||
OK
|
||||
127.0.0.1:6379> SETNX existing_key "The key is no longer free, so this will fail."
|
||||
(nil)
|
||||
127.0.0.1:6379> SET nonexistent_key "This doesn't exist." XX
|
||||
(nil)
|
||||
```
|
||||
|
||||
As you can see, if a `SET` operation is successful, it returns `OK`, otherwise it returns nothing, represented as `(nil)` in the CLI. Both the expiration time, and the create if (not) exists options can be set in the basic `SET` command as well.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> SET magical_key "This key has several options set." EX 10 NX
|
||||
OK
|
||||
```
|
||||
|
||||
Now, let's check out some more complex datatypes. One of the datatypes that Redis supports are hashes. Like hashes in any programming language, one key has many fields.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> HSET example_hash name "Caff"
|
||||
(integer) 1
|
||||
127.0.0.1:6379> HSET example_hash age 24
|
||||
(integer) 1
|
||||
127.0.0.1:6379> HGET example_hash
|
||||
(error) ERR wrong number of arguments for 'hget' command
|
||||
127.0.0.1:6379> GET example_hash
|
||||
(error) WRONGTYPE Operation against a key holding the wrong kind of value
|
||||
127.0.0.1:6379> HGETALL example_hash
|
||||
1) "name"
|
||||
2) "Caff"
|
||||
3) "age"
|
||||
4) "24"
|
||||
127.0.0.1:6379> HGET example_hash name
|
||||
"Caff"
|
||||
```
|
||||
|
||||
You can also set multiple fields in a single command. The number it returns is the number of new fields created, so updating existing fields doesn't increase that number.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> HSET example_hash discord "The Programmer's Hangout" discriminator "0001" age 25
|
||||
(integer) 2
|
||||
127.0.0.1:6379> HGETALL example_hash
|
||||
1) "name"
|
||||
2) "Caff"
|
||||
3) "age"
|
||||
4) "25"
|
||||
5) "discord"
|
||||
6) "The Programmer's Hangout"
|
||||
7) "discriminator"
|
||||
8) "0001"
|
||||
```
|
||||
|
||||
Another datastructure is Sorted Sets. These are essentially arrays, in which each item has a score. `ZRANGE` allows you to retrieve a range of items in the sorted set, ordered by score. It allows you to provide indexes, starting at zero. Negative indexes are from the end of the set, so `0 -1` means all items in the set, since -1 is the last item.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> ZADD high_scores 100000 "PinballWizard" 80000 "Elliott" 50000 "Caff" 25000 "HotBot"
|
||||
(integer) 4
|
||||
127.0.0.1:6379> ZRANGE high_scores 0 -1 WITHSCORES
|
||||
1) "HotBot"
|
||||
2) "25000"
|
||||
3) "Caff"
|
||||
4) "50000"
|
||||
5) "Elliott"
|
||||
6) "80000"
|
||||
7) "PinballWizard"
|
||||
8) "100000"
|
||||
```
|
||||
|
||||
By default, Redis sorts by the lowest scores first. For sorting/displaying data, Redis also provides reversed functions for displaying the highest scores first.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> ZREVRANGE high_scores 0 -1 WITHSCORES
|
||||
1) "PinballWizard"
|
||||
2) "100000"
|
||||
3) "Elliott"
|
||||
4) "80000"
|
||||
5) "Caff"
|
||||
6) "50000"
|
||||
7) "HotBot"
|
||||
8) "25000"
|
||||
127.0.0.1:6379> ZREVRANK high_scores "PinballWizard"
|
||||
(integer) 0
|
||||
```
|
||||
|
||||
Redis also has some functions for geospatial data. Internally, Geospatial data is stored using a sorted set. The Geo functions allow you to get the distance between two members, get all members within a radius of a certain point/member.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> GEOADD some_cities 2.354493 48.862773 "Paris" -0.117431 51.506906 "London" 10.000977 53.538554 "Hamburg" 21.01412 52.210929 "Warsaw" -122.423435 37.771993 "San Francisco" 37.649808 55.753146 "Moscow" 72.911566 19.093070 "Mumbai" 18.500058 -33.865797 "Cape Town"
|
||||
(integer) 8
|
||||
127.0.0.1:6379> GEODIST some_cities "London" "Hamburg" km
|
||||
"720.3475"
|
||||
127.0.0.1:6379> GEODIST some_cities "London" "Hamburg" mi
|
||||
"447.6043"
|
||||
127.0.0.1:6379> GEORADIUS some_cities 5 50 2000 mi WITHCOORD WITHDIST
|
||||
1) 1) "Paris"
|
||||
2) "142.5253"
|
||||
3) 1) "2.35449403524398804"
|
||||
2) "48.86277411109344371"
|
||||
2) 1) "Warsaw"
|
||||
2) "709.9603"
|
||||
3) 1) "21.01411789655685425"
|
||||
2) "52.21092784600281789"
|
||||
3) 1) "Hamburg"
|
||||
2) "324.7380"
|
||||
3) 1) "10.00097841024398804"
|
||||
2) "53.53855395595674338"
|
||||
4) 1) "Moscow"
|
||||
2) "1403.9739"
|
||||
3) 1) "37.64980584383010864"
|
||||
2) "55.75314490231349396"
|
||||
5) 1) "London"
|
||||
2) "246.7366"
|
||||
3) 1) "-0.11742979288101196"
|
||||
2) "51.50690650927526804"
|
||||
```
|
||||
|
||||
Redis also offers a publish/subscription system, to listen for real-time events via channels.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> SUBSCRIBE tweets
|
||||
Reading messages... (press Ctrl-C to quit)
|
||||
1) "subscribe"
|
||||
2) "tweets"
|
||||
3) (integer) 1
|
||||
```
|
||||
|
||||
Another client could then run `PUBLISH` to push messages to all listening clients.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> PUBLISH tweets "@RedisLabs just tweeted \"This is a Redis example.\""
|
||||
(integer) 1
|
||||
```
|
||||
|
||||
The listening clients would then receive the following.
|
||||
|
||||
```
|
||||
1) "message"
|
||||
2) "tweets"
|
||||
3) "@TheProgrammersHangout just tweeted \"This is a Redis example.\""
|
||||
```
|
||||
|
||||
Redis' pub/sub implementation also supports pattern-matching for channels.
|
||||
|
||||
```
|
||||
127.0.0.1:6379> PSUBSCRIBE tweets:*
|
||||
Reading messages... (press Ctrl-C to quit)
|
||||
1) "psubscribe"
|
||||
2) "tweets:*"
|
||||
3) (integer) 1
|
||||
```
|
||||
|
||||
Any messages published to channels beginning with `tweets:` would be retireved by the subcribed client. Redis supports single-character wildcards (`?`), multi-character wildcards (`*`), and character groups (`[abcd]`) in its pattern subscriptions.
|
||||
|
||||
If the following messages were published:
|
||||
|
||||
```
|
||||
127.0.0.1:6379> PUBLISH tweets:follow "John just followed."
|
||||
(integer) 1
|
||||
127.0.0.1:6379> PUBLISH tweets:retweet "Eric retweeted your Tweet"
|
||||
(integer) 1
|
||||
```
|
||||
|
||||
A subscribed client would recieve the following:
|
||||
|
||||
```
|
||||
1) "pmessage"
|
||||
2) "tweets:*"
|
||||
3) "tweets:follow"
|
||||
4) "John just followed."
|
||||
|
||||
1) "pmessage"
|
||||
2) "tweets:*"
|
||||
3) "tweets:retweet"
|
||||
4) "Eric retweeted your Tweet"
|
||||
```
|
||||
|
||||
Redis supports a lot more features, like clustering, transactions, scripting, and more datatypes like HyperLogLogs and Streams, this is just a taste of Redis' usefulness. In addition, Redis' functionality can be extended via scripts and modules.
|
||||
|
||||
**More Resources**
|
||||
|
||||
- https://redis.io/commands
|
||||
- https://try.redis.io/
|
||||
- https://redislabs.com/community/ebook/
|
||||
- https://redislabs.com/community/redis-modules-hub/
|
||||
- https://hub.docker.com/_/redis/
|
||||
- https://github.com/antirez/redis
|
||||
- https://redis.io/topics/persistence
|
||||
- https://www.paperplanes.de/2010/2/16/a_collection_of_redis_use_cases.html
|
||||
- https://redditblog.com/2017/04/13/how-we-built-rplace/
|
||||
- https://www.objectrocket.com/blog/how-to/10-quick-tips-about-redis/
|
||||
@@ -0,0 +1,160 @@
|
||||
**What is Rust?**
|
||||
|
||||
"Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety."
|
||||
In other terms, Rust is a language that offers the performance of C or C++ along with some higher level constructs
|
||||
that let the compiler figure out whether or not your code is safe.
|
||||
But what is safe? Safe here means that your program shouldn't leak memory, access uninitialised or undefined
|
||||
memory, or yield odd results because of race conditions in your code. Rust, similar to C++, offers what
|
||||
are called "Zero-cost" abstractions, which in essence means that the idiomatic/ pretty way of writing a piece
|
||||
of code will be as performant as writing your own code.
|
||||
|
||||
**How is Rust safe?**
|
||||
|
||||
Rust adds an extra layer of safety by having a concept of ownership at the type level, and by
|
||||
strongly distinguishing mutability over immutability. By keeping track of where a resource is owned,
|
||||
the compiler can figure out at compile time when that resource can safely be destroyed, thus preventing
|
||||
a large class of bugs related to manual memory management.
|
||||
Rust also uses this ownership system to keep track of resource management across threads, thus preventing
|
||||
data races.
|
||||
|
||||
Like C and C++, Rust doesn't have any garbage collection, but unlike C, and to a lesser extent C++,
|
||||
Rust doesn't have manual memory management. Because of this ownership system, the compiler figures
|
||||
out when to safely drop resources. Unlike in C, where you could leak memory by forgetting to free
|
||||
some resource, or crash your program by using memory that has already been freed, Rust avoids errors like
|
||||
these by keeping track of who owns what resource at compile time.
|
||||
|
||||
**What high level constructs does Rust offer?**
|
||||
|
||||
Rust comes with a very good standard library, if you're not building on an embedded platform, of course.
|
||||
The standard library allows you to work with vectors and arrays using concise .maps and .filters instead
|
||||
of your standard for loop. In addition to constructs provided by the standard library, the language itself
|
||||
has common modern language features, such as modules, structs, and anonymous functions (closures).
|
||||
One of the more unique Rust features is Traits, which are like Interfaces, but in reverse. Instead of a Struct
|
||||
inheriting from an Interface when it's defined, a Trait is defined after a Struct, and then the implementation of
|
||||
that Trait for the Struct may be defined. This allows you to create new interfaces and have pre-existing types
|
||||
adhere to them. This offers a bit more extensibility than the traditional interface system.
|
||||
|
||||
Another newer feature Rust has is pattern matching, which allows you to match not and branch code not only
|
||||
on the simple value of data, but also on its structure. For example instead of matching on a simple integer value,
|
||||
you can match on a hashmap with a certain value at a certain key.
|
||||
|
||||
One of the external aspects that makes the language easy to work with is the build tool "Cargo". Cargo
|
||||
makes fetching dependencies for a project and building a project a breeze!
|
||||
|
||||
**Where do I get Rust?**
|
||||
|
||||
Installation instructions can be found here: https://www.rust-lang.org/en-US/install.html
|
||||
|
||||
**Where do I learn more?**
|
||||
|
||||
Rust has a great book for learning the language, that can be found here (online book): https://doc.rust-lang.org/book/second-edition/index.html
|
||||
|
||||
**Code Examples**
|
||||
|
||||
**Hello World**
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
println!("Hello World!");
|
||||
}
|
||||
```
|
||||
|
||||
**Pattern Matching Example**
|
||||
|
||||
```rust
|
||||
fn main() {
|
||||
let p = Point { x: 0, y: 7 };
|
||||
|
||||
match p {
|
||||
Point { x, y: 0 } => println!("On the x axis at {}", x),
|
||||
Point { x: 0, y } => println!("On the y axis at {}", y),
|
||||
Point { x, y } => println!("On neither axis: ({}, {})", x, y),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Sum of Squared Odd Numbers under 1000**
|
||||
|
||||
```rust
|
||||
fn is_odd(n: u32) -> bool {
|
||||
n % 2 == 1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Find the sum of all the squared odd numbers under 1000");
|
||||
let upper = 1000;
|
||||
|
||||
// Imperative approach
|
||||
// Declare accumulator variable
|
||||
let mut acc = 0;
|
||||
// Iterate: 0, 1, 2, ... to infinity
|
||||
for n in 0.. {
|
||||
// Square the number
|
||||
let n_squared = n * n;
|
||||
|
||||
if n_squared >= upper {
|
||||
// Break loop if exceeded the upper limit
|
||||
break;
|
||||
} else if is_odd(n_squared) {
|
||||
// Accumulate value, if it's odd
|
||||
acc += n_squared;
|
||||
}
|
||||
}
|
||||
println!("imperative style: {}", acc);
|
||||
|
||||
// Functional approach
|
||||
let sum_of_squared_odd_numbers: u32 =
|
||||
(0..).map(|n| n * n) // All natural numbers squared
|
||||
.take_while(|&n_squared| n_squared < upper) // Below upper limit
|
||||
.filter(|&n_squared| is_odd(n_squared)) // That are odd
|
||||
.fold(0, |acc, n_squared| acc + n_squared); // Sum them
|
||||
|
||||
println!("functional style: {}", sum_of_squared_odd_numbers);
|
||||
}
|
||||
```
|
||||
|
||||
**Traits Example**
|
||||
|
||||
```rust
|
||||
pub trait Summary {
|
||||
fn summarize(&self) -> String;
|
||||
}
|
||||
|
||||
pub struct NewsArticle {
|
||||
pub headline: String,
|
||||
pub location: String,
|
||||
pub author: String,
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
impl Summary for NewsArticle {
|
||||
fn summarize(&self) -> String {
|
||||
format!("{}, by {} ({})", self.headline, self.author, self.location)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Tweet {
|
||||
pub username: String,
|
||||
pub content: String,
|
||||
pub reply: bool,
|
||||
pub retweet: bool,
|
||||
}
|
||||
|
||||
impl Summary for Tweet {
|
||||
fn summarize(&self) -> String {
|
||||
format!("{}: {}", self.username, self.content)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let tweet = Tweet {
|
||||
username: String::from("horse_ebooks"),
|
||||
content: String::from("of course, as you probably already know, people"),
|
||||
reply: false,
|
||||
retweet: false,
|
||||
};
|
||||
|
||||
// 1 new tweet: horse_ebooks: of course, as you probably already know, people
|
||||
println!("1 new tweet: {}", tweet.summarize());
|
||||
}
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
authors:
|
||||
- "ddivad#1337"
|
||||
- "ddivad#0001"
|
||||
created_at: "2019/10/01"
|
||||
title: Async Await
|
||||
recommended_reading:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
authors:
|
||||
- "ddivad#1337"
|
||||
- "ddivad#0001"
|
||||
created_at: "2019/10/06"
|
||||
title: Variables
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user