<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wiki.squi.fr/index.php?action=history&amp;feed=atom&amp;title=Rust_%3A_g%C3%A9n%C3%A9riques%2C_traits%2C_lifetimes</id>
	<title>Rust : génériques, traits, lifetimes - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.squi.fr/index.php?action=history&amp;feed=atom&amp;title=Rust_%3A_g%C3%A9n%C3%A9riques%2C_traits%2C_lifetimes"/>
	<link rel="alternate" type="text/html" href="https://wiki.squi.fr/index.php?title=Rust_:_g%C3%A9n%C3%A9riques,_traits,_lifetimes&amp;action=history"/>
	<updated>2026-06-12T02:39:36Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.squi.fr/index.php?title=Rust_:_g%C3%A9n%C3%A9riques,_traits,_lifetimes&amp;diff=2365&amp;oldid=prev</id>
		<title>Justine le 3 novembre 2022 à 09:21</title>
		<link rel="alternate" type="text/html" href="https://wiki.squi.fr/index.php?title=Rust_:_g%C3%A9n%C3%A9riques,_traits,_lifetimes&amp;diff=2365&amp;oldid=prev"/>
		<updated>2022-11-03T09:21:06Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;fr&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Version précédente&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version du 3 novembre 2022 à 09:21&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Ligne 1 :&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Ligne 1 :&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt; &lt;/del&gt;&amp;lt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;nowiki&lt;/del&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;syntaxhighlight lang=&#039;rust&#039;&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;//1 - Generic Data Types&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;//1 - Generic Data Types&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     //Le but principal est de diminuer la duplication de code.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;     //Le but principal est de diminuer la duplication de code.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l497&quot;&gt;Ligne 497 :&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Ligne 497 :&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;nowiki&lt;/del&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;syntaxhighlight&lt;/ins&gt;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key mediawiki-mediawiki:diff:1.41:old-2357:rev-2365:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Justine</name></author>
	</entry>
	<entry>
		<id>https://wiki.squi.fr/index.php?title=Rust_:_g%C3%A9n%C3%A9riques,_traits,_lifetimes&amp;diff=2357&amp;oldid=prev</id>
		<title>Justine : Page créée avec «  &lt;nowiki&gt; //1 - Generic Data Types     //Le but principal est de diminuer la duplication de code.     //Les génériques sont utilisés pour créer par exemple des signatures de     //fonction ou des structs.           //Dans une fonction     //Par exemple ici, je veux extraire le plus gros chiffe d&#039;une liste de i32     //et le plus gros char d&#039;une liste de chars (pas un String); je pourrais     //faire 2 fonctions, ou une seule avec un générique.     //     //... »</title>
		<link rel="alternate" type="text/html" href="https://wiki.squi.fr/index.php?title=Rust_:_g%C3%A9n%C3%A9riques,_traits,_lifetimes&amp;diff=2357&amp;oldid=prev"/>
		<updated>2022-11-03T09:16:13Z</updated>

		<summary type="html">&lt;p&gt;Page créée avec «  &amp;lt;nowiki&amp;gt; //1 - Generic Data Types     //Le but principal est de diminuer la duplication de code.     //Les génériques sont utilisés pour créer par exemple des signatures de     //fonction ou des structs.           //Dans une fonction     //Par exemple ici, je veux extraire le plus gros chiffe d&amp;#039;une liste de i32     //et le plus gros char d&amp;#039;une liste de chars (pas un String); je pourrais     //faire 2 fonctions, ou une seule avec un générique.     //     //... »&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt; &amp;lt;nowiki&amp;gt;&lt;br /&gt;
//1 - Generic Data Types&lt;br /&gt;
    //Le but principal est de diminuer la duplication de code.&lt;br /&gt;
    //Les génériques sont utilisés pour créer par exemple des signatures de&lt;br /&gt;
    //fonction ou des structs.&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    //Dans une fonction&lt;br /&gt;
    //Par exemple ici, je veux extraire le plus gros chiffe d&amp;#039;une liste de i32&lt;br /&gt;
    //et le plus gros char d&amp;#039;une liste de chars (pas un String); je pourrais&lt;br /&gt;
    //faire 2 fonctions, ou une seule avec un générique.&lt;br /&gt;
    //&lt;br /&gt;
    //Je commence par noter mon générique (qui est en gros un placeholder&lt;br /&gt;
    // pour le type) entre chevrons. Souvent noté T par convention.&lt;br /&gt;
    //&lt;br /&gt;
    //La signature suivante signifie:&lt;br /&gt;
    //&amp;quot;La fonction largest est générique sur un type noté T. Elle prend&lt;br /&gt;
    //en paramètre une ref vers une liste d&amp;#039;objets de type T, et renvoie&lt;br /&gt;
    //une ref vers un objet de type T&amp;quot;.&lt;br /&gt;
fn largest&amp;lt;T&amp;gt;(list: &amp;amp;[T]) -&amp;gt; &amp;amp;T {&lt;br /&gt;
    let mut largest = &amp;amp;list[0];&lt;br /&gt;
&lt;br /&gt;
    for item in list {&lt;br /&gt;
        if item &amp;gt; largest {&lt;br /&gt;
            largest = item;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    largest&lt;br /&gt;
}&lt;br /&gt;
    //Ici, T n&amp;#039;est pas restreint : il peut prendre n&amp;#039;importe quel type.&lt;br /&gt;
    //D&amp;#039;ailleurs, ça compile pas : l&amp;#039;opérateur &amp;gt; ne fonctionne&lt;br /&gt;
    //pas avec tous les types, alors le compilateur il gueule.&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    //Dans un struct&lt;br /&gt;
    //On peut aussi définir un struct en utilisant un générique.&lt;br /&gt;
struct Point&amp;lt;T&amp;gt; {&lt;br /&gt;
    x: T,&lt;br /&gt;
    y:T&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
fn main() {&lt;br /&gt;
    let integer = Point { x:5, y:10 };&lt;br /&gt;
    let float = Point { x:1.0,, y:4.0 };&lt;br /&gt;
    //Ici, on a que T donc les 2 valeurs doivent être du même type&lt;br /&gt;
    //let marchepas = Point {x:5, y:4.2};&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    //Dans ce genre de cas on peut utiliser 2 génériques&lt;br /&gt;
struct Point2&amp;lt;T, U&amp;gt; {&lt;br /&gt;
    x: T,&lt;br /&gt;
    y: U&lt;br /&gt;
}&lt;br /&gt;
    //Appellable avec let bidule = Point {x: 4, y: 5.2 };&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //Dans un enum&lt;br /&gt;
    //Option&amp;lt;T&amp;gt; le fait déjà:&lt;br /&gt;
    //enum Option&amp;lt;T&amp;gt; {&lt;br /&gt;
    //  Some(T),&lt;br /&gt;
    //  None,&lt;br /&gt;
    //}&lt;br /&gt;
    //&lt;br /&gt;
    //Result a 2 génériques&lt;br /&gt;
    //enum Result&amp;lt;T, E&amp;gt; {&lt;br /&gt;
    //  Ok(T),&lt;br /&gt;
    //  Err(E)&lt;br /&gt;
    //}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //Dans une méthode&lt;br /&gt;
    //Même idée : le générique utilisé pour mon struct peut être&lt;br /&gt;
    //réutilisé dans les méthodes du Struct&lt;br /&gt;
struct Point2&amp;lt;T&amp;gt; {&lt;br /&gt;
    x: T,&lt;br /&gt;
    y: T&lt;br /&gt;
}&lt;br /&gt;
impl&amp;lt;T&amp;gt; Point2&amp;lt;T&amp;gt; {&lt;br /&gt;
    fn x(&amp;amp;self) -&amp;gt; &amp;amp;T {&lt;br /&gt;
        &amp;amp;self.x&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
    //Cependant on a une autre possibilité : &lt;br /&gt;
    //Réserver une méthode au cas où T est d&amp;#039;un type précis,&lt;br /&gt;
    //par exemple f32:&lt;br /&gt;
impl Point2&amp;lt;f32&amp;gt;{&lt;br /&gt;
    fn distance_from_origin(&amp;amp;self) -&amp;gt; f32 {&lt;br /&gt;
        (self.x.powi(2) + self.y.powi(2)).sqrt()&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
    //Ici, un Point2&amp;lt;f32&amp;gt; aura la méthode distance_from_origin;&lt;br /&gt;
    //un Point&amp;lt;i32&amp;gt; ne l&amp;#039;aura pas.&lt;br /&gt;
    //Enfin, les méthodes peuvent avoir des génériques en plus.&lt;br /&gt;
    //Exemple : &lt;br /&gt;
struct Point&amp;lt;X1, Y1&amp;gt; {&lt;br /&gt;
    x: X1,&lt;br /&gt;
    y: Y1,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl&amp;lt;X1, Y1&amp;gt; Point&amp;lt;X1, Y1&amp;gt; {&lt;br /&gt;
    fn mixup&amp;lt;X2, Y2&amp;gt;(self, other: Point&amp;lt;X2, Y2&amp;gt;) -&amp;gt; Point&amp;lt;X1, Y2&amp;gt; {&lt;br /&gt;
        Point {&lt;br /&gt;
            x: self.x,&lt;br /&gt;
            y: other.y,&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    let p1 = Point { x: 5, y: 10.4 };&lt;br /&gt;
    let p2 = Point { x: &amp;quot;Hello&amp;quot;, y: &amp;#039;c&amp;#039; };&lt;br /&gt;
&lt;br /&gt;
    let p3 = p1.mixup(p2);&lt;br /&gt;
&lt;br /&gt;
    println!(&amp;quot;p3.x = {}, p3.y = {}&amp;quot;, p3.x, p3.y);&lt;br /&gt;
}&lt;br /&gt;
    //Les génériques n&amp;#039;ont pas spécialement de coût en performances.&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
// ----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
// Traits : Defining Shared Behavior&lt;br /&gt;
&lt;br /&gt;
    //Un trait définit une fonctionnalité qu&amp;#039;un type a et peut partager avec &lt;br /&gt;
    //d&amp;#039;autres types; on parle de shared behaviour. &lt;br /&gt;
    //On peut utiliser un &amp;quot;trait bound&amp;quot; pour spếcifier &lt;br /&gt;
    //qu&amp;#039;un générique peut être de n&amp;#039;importe quel type ayant tel ou tel trait.&lt;br /&gt;
&lt;br /&gt;
    //Definir un trait&lt;br /&gt;
    //L&amp;#039;attitude (behaviour) d&amp;#039;un type, c&amp;#039;est ses méthodes. Elles sont&lt;br /&gt;
    //partagées si plusieurs types ont la même. Les traits sont une façon&lt;br /&gt;
    //de grouper des signatures de méthodes pour définir des ensembles&lt;br /&gt;
    //d&amp;#039;attitudes.&lt;br /&gt;
    &lt;br /&gt;
    //Exemple, on veut grouper des articles de presse et des tweets. &lt;br /&gt;
    //Chacun à un struct, et tous ont une méthode qui renvoie un résumé;&lt;br /&gt;
    //cependant un tweet n&amp;#039;est pas fait comme un article de presse !&lt;br /&gt;
pub trait Summary {&lt;br /&gt;
    fn summarize(&amp;amp;self) -&amp;gt; String;&lt;br /&gt;
}&lt;br /&gt;
    //On a juste la signature; chaque type ayant ce trait devra fournir sa&lt;br /&gt;
    //propre implémentation. Le compilateur s&amp;#039;attendra à ce que chaque type&lt;br /&gt;
    //ayant le trait Summary ait une méthode summarize.&lt;br /&gt;
    //Un trait peut avoir plusieurs méthodes.&lt;br /&gt;
    &lt;br /&gt;
    //Implémenter le trait&lt;br /&gt;
pub struct NewsArticle {&lt;br /&gt;
    pub headline: String,&lt;br /&gt;
    pub location: String,&lt;br /&gt;
    pub author: String,&lt;br /&gt;
    pub content: String,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//C&amp;#039;est comme ça qu&amp;#039;on donne le trait Summarize a NewsArticle&lt;br /&gt;
impl Summary for NewsArticle {&lt;br /&gt;
    fn summarize(&amp;amp;self) -&amp;gt; String {&lt;br /&gt;
        format!(&amp;quot;{}, by {} ({})&amp;quot;, self.headline, self.author, self.location)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pub struct Tweet {&lt;br /&gt;
    pub username: String,&lt;br /&gt;
    pub content: String,&lt;br /&gt;
    pub reply: bool,&lt;br /&gt;
    pub retweet: bool,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl Summary for Tweet {&lt;br /&gt;
    fn summarize(&amp;amp;self) -&amp;gt; String {&lt;br /&gt;
        format!(&amp;quot;{}: {}&amp;quot;, self.username, self.content)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
    &lt;br /&gt;
//On pourrait par la suite appeller le type tweet et son trait avec ceci,&lt;br /&gt;
//en admettant que j&amp;#039;ai mis ça dans une lib nommée aggregator&lt;br /&gt;
//use aggregator::{Summary, Tweet}&lt;br /&gt;
//&lt;br /&gt;
//À noter : on ne peut implémenter un trait sur un type que si le trait &lt;br /&gt;
//ou (OR) le type est local&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Avoir une méthode par défaut&lt;br /&gt;
//On peut avoir une méthode par défaut associée à chaque signature de fonction&lt;br /&gt;
//donnée dans notre trait; on pourra la conserver ou l&amp;#039;override lors de &lt;br /&gt;
//l&amp;#039;implémentation.&lt;br /&gt;
pub trait Summary {&lt;br /&gt;
    fn summarize(&amp;amp;self) -&amp;gt; String {&lt;br /&gt;
        String::from(&amp;quot;(Read more...)&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Pour avoir la méthode par défaut, on DOIT donner une implémentation vide.&lt;br /&gt;
impl Summary for NewsArticle {}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Une implémentation par défaut peut appeller d&amp;#039;autre méthodes du même trait,&lt;br /&gt;
//même si ces dernières ne sont pas dans l&amp;#039;implémentation par défaut.&lt;br /&gt;
pub trait Summary {&lt;br /&gt;
    fn summarize_author(&amp;amp;self) -&amp;gt; String;&lt;br /&gt;
&lt;br /&gt;
    fn summarize(&amp;amp;self) -&amp;gt; String {&lt;br /&gt;
        format!(&amp;quot;(Read more from {}...)&amp;quot;, self.summarize_author())&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
//Ici, mon implémentation n&amp;#039;as besoin de définir que summarize_author&lt;br /&gt;
impl Summary for Tweet {&lt;br /&gt;
    fn summarize_author(&amp;amp;self) -&amp;gt; String {&lt;br /&gt;
        format!(&amp;quot;@{}&amp;quot;, self.username)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Traits comme paramètre&lt;br /&gt;
//Du coup, on peut créer une fonction prenant pour paramètre un objet&lt;br /&gt;
//dont on précise non pas son type, mais un trait qu&amp;#039;il doit avoir.&lt;br /&gt;
pub fn notify(item: &amp;amp;impl Summary) {&lt;br /&gt;
    println!(&amp;quot;Breaking news! {}&amp;quot;, item.summarize());&lt;br /&gt;
}&lt;br /&gt;
//Ici, je me fiche de savoir quel est le type de &amp;quot;item&amp;quot;, simplement, qu&amp;#039;il&lt;br /&gt;
//doit avoir le trait Summary.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//Trait Bound&lt;br /&gt;
//La syntaxe ci-dessus fonctionne dans les cas simple, mais en réalité&lt;br /&gt;
//c&amp;#039;est juste du sucre syntaxique pour la forme suivante nommée trait bound:&lt;br /&gt;
pub fn notify&amp;lt;T: Summary&amp;gt;(item: &amp;amp;T) {&lt;br /&gt;
    println!(&amp;quot;Breaking news! {}&amp;quot;, item.summarize());&lt;br /&gt;
}&lt;br /&gt;
//La forme &amp;quot;&amp;amp;impl Trait&amp;quot; est pratique et permet de raccourcir.&lt;br /&gt;
//On peut avoir 2 paramètres qui doivent avoir un trait peu importe&lt;br /&gt;
//leur type, par ex:&lt;br /&gt;
pub fn notify(item1: &amp;amp;impl Summary, item2: &amp;amp;impl Summary) {&lt;br /&gt;
    println!(&amp;quot;Whatever&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
//...mais si ils doivent avoir le même type il nous faut un trait bound (super)&lt;br /&gt;
pub fn notify&amp;lt;T: Summary&amp;gt;(item1: &amp;amp;T, item2: &amp;amp;T) {&lt;br /&gt;
    println!(&amp;quot;Whatever&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//On peut aussi avoir un bound sur 2 traits à la fois.&lt;br /&gt;
pub fn notify(item: &amp;amp;(impl Summary + Display)) {&lt;br /&gt;
    println!(&amp;quot;Whatever&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
//Ça marche aussi en trait bound&lt;br /&gt;
pub fn notify&amp;lt;T: Summary + Display&amp;gt;(item: &amp;amp;T) {&lt;br /&gt;
    println!(&amp;quot;Whatever&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
//On a un syntaxe alternative si on a beaucoup de trait bound, pour rendre&lt;br /&gt;
//ça plus lisible&lt;br /&gt;
//Par exemple transformer ça:&lt;br /&gt;
fn some_function&amp;lt;T: Display + Clone, U: Clone + Debug&amp;gt;(t: &amp;amp;T, u: &amp;amp;U) -&amp;gt; i32 {&lt;br /&gt;
    //[...]&lt;br /&gt;
}&lt;br /&gt;
//...en ça avec le mot-clef where&lt;br /&gt;
fn some_function&amp;lt;T, U&amp;gt;(t: &amp;amp;T, u: &amp;amp;U) -&amp;gt; i32&lt;br /&gt;
where&lt;br /&gt;
    T: Display + Clone,&lt;br /&gt;
    U: Clone + Debug,&lt;br /&gt;
{&lt;br /&gt;
    //[...]&lt;br /&gt;
}&lt;br /&gt;
//Quel foutoir !&lt;br /&gt;
&lt;br /&gt;
//Trait bound, mais sur le retour de la fonction&lt;br /&gt;
//On peut appliquer le principe du trait bound à la valeur de retour d&amp;#039;une&lt;br /&gt;
//fonction:&lt;br /&gt;
fn returns_summarizable() -&amp;gt; impl Summary {&lt;br /&gt;
    Tweet {&lt;br /&gt;
        username: String::from(&amp;quot;horse_ebooks&amp;quot;),&lt;br /&gt;
        content: String::from(&lt;br /&gt;
            &amp;quot;of course, as you probably already know, people&amp;quot;,&lt;br /&gt;
        ),&lt;br /&gt;
        reply: false,&lt;br /&gt;
        retweet: false,&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
//Ici, ma valeur de retour peut avoir n&amp;#039;importe quel type ayant le trait&lt;br /&gt;
//Summary. Mais en fait non : si ma fonction peut renvoyer plusieurs types &lt;br /&gt;
//différents (par exemple un tweet ou un NewsArticle en fonction des cas),&lt;br /&gt;
//le compilateur plantera. Zut !&lt;br /&gt;
&lt;br /&gt;
//Trait bounds pour implémentation conditionnelles de méthodes&lt;br /&gt;
//Alors, en plus on peut faire des trait bounds sur des implémentations&lt;br /&gt;
//pour dire qu&amp;#039;un objet aura telle méthode seulement si il a tel trait:&lt;br /&gt;
use std::fmt::Display;&lt;br /&gt;
&lt;br /&gt;
struct Pair&amp;lt;T&amp;gt; {&lt;br /&gt;
    x: T,&lt;br /&gt;
    y: T,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl&amp;lt;T&amp;gt; Pair&amp;lt;T&amp;gt; {&lt;br /&gt;
    fn new(x: T, y: T) -&amp;gt; Self {&lt;br /&gt;
        Self { x, y }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
impl&amp;lt;T: Display + PartialOrd&amp;gt; Pair&amp;lt;T&amp;gt; {&lt;br /&gt;
    fn cmp_display(&amp;amp;self) {&lt;br /&gt;
        if self.x &amp;gt;= self.y {&lt;br /&gt;
            println!(&amp;quot;The largest member is x = {}&amp;quot;, self.x);&lt;br /&gt;
        } else {&lt;br /&gt;
            println!(&amp;quot;The largest member is y = {}&amp;quot;, self.y);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
//Ici, un objet de type Pair aura toujours la méthode new, sa methode getter;&lt;br /&gt;
//Mais il n&amp;#039;aura la méthode cmp.display QUE si il a le trait Display ET le trait&lt;br /&gt;
//PartialOrd. &lt;br /&gt;
&lt;br /&gt;
//On peut aussi implémenter un trait pour n&amp;#039;importe quel type qui implémente&lt;br /&gt;
//un autre trait; c&amp;#039;est très utilisé dans la lib standard, par exemple pour&lt;br /&gt;
//ToString qui est implémenté seulement si le type a le trait Display.&lt;br /&gt;
impl&amp;lt;T: Display&amp;gt; ToString for T {&lt;br /&gt;
    // --snip--&lt;br /&gt;
}&lt;br /&gt;
//Cela s&amp;#039;appelle une &amp;quot;blanket implementation&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
//-------------------------------------------------------&lt;br /&gt;
//&lt;br /&gt;
// Lifetimes : Validating References &lt;br /&gt;
//&lt;br /&gt;
// Les lifetimes sont aussi des génériques. Ils servent à s&amp;#039;assurer qu&amp;#039;une&lt;br /&gt;
// référence est valide tant qu&amp;#039;on en a besoin.&lt;br /&gt;
//&lt;br /&gt;
// Toute &amp;amp;référence a un lifetime, soit un scope dans lequel elle est valide.&lt;br /&gt;
// Elles sont la plupart du temps implicite, comme les types.&lt;br /&gt;
// Et comme les types, il faut les préciser quand ce n&amp;#039;est pas déductible.&lt;br /&gt;
// C&amp;#039;est une notion unique à Rust.&lt;br /&gt;
&lt;br /&gt;
//EXPLICATIONS PREALABLES&lt;br /&gt;
//Le but des lifetime est d&amp;#039;éviter les références &amp;quot;dangling&amp;quot;, qui ne mène&lt;br /&gt;
//plus nulle part.&lt;br /&gt;
//Exemple:&lt;br /&gt;
fn main() {&lt;br /&gt;
    //On peut faire ce genre d&amp;#039;assignation sans valeur&lt;br /&gt;
    //mais le compilateur plantera si on ne donne pas une valeur à r&lt;br /&gt;
    //avant de l&amp;#039;utiliser (no null values in Rust).&lt;br /&gt;
    //À eviter, je suppose.&lt;br /&gt;
    let r;&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        let x = 5;&lt;br /&gt;
        r = &amp;amp;x;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    println!(&amp;quot;r: {}&amp;quot;, r);&lt;br /&gt;
}&lt;br /&gt;
//r mène à x, mais x n&amp;#039;existe plus lors du println!.&lt;br /&gt;
//Rust le détermine à l&amp;#039;aide de son &amp;quot;Borrow Checker&amp;quot;; celui-ci vérifie&lt;br /&gt;
//les emprunts. Même code qu&amp;#039;au dessus, mais on montre les lifetimes.&lt;br /&gt;
//notés &amp;#039;a et &amp;#039;b.&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    let r;                // ---------+-- &amp;#039;a&lt;br /&gt;
                          //          |&lt;br /&gt;
    {                     //          |&lt;br /&gt;
        let x = 5;        // -+-- &amp;#039;b  |&lt;br /&gt;
        r = &amp;amp;x;           //  |       |&lt;br /&gt;
    }                     // -+       |&lt;br /&gt;
                          //          |&lt;br /&gt;
    println!(&amp;quot;r: {}&amp;quot;, r); //          |&lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
//APPLICATION&lt;br /&gt;
//Prenons le code suivant, qui compare des string slices (qui sont par nature&lt;br /&gt;
//des références), et qui ne compilera pas :&lt;br /&gt;
fn longest(x: &amp;amp;str, y: &amp;amp;str) -&amp;gt; &amp;amp;str {&lt;br /&gt;
    if x.len() &amp;gt; y.len() {&lt;br /&gt;
        x&lt;br /&gt;
    } else {&lt;br /&gt;
        y&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
//Ici le compilateur nous donnera une erreur pour réclamer un lifetime parameter&lt;br /&gt;
//pour le retour.&lt;br /&gt;
//En effet, on ne sait pas à quoi la référence renvoyée fera référence à cause&lt;br /&gt;
//du if !&lt;br /&gt;
// On va ajouter des generic lifetime parameters.&lt;br /&gt;
&lt;br /&gt;
//Les annotation de lifetime ne changent pas la durée de vie des références.&lt;br /&gt;
//Elles servent juste à décrire les relation des lifetimes et n&amp;#039;ont pas de sens&lt;br /&gt;
//si je n&amp;#039;en ai qu&amp;#039;une.&lt;br /&gt;
//Une fonction peut accepter un lifetime générique de la même façon&lt;br /&gt;
//qu&amp;#039;elle peut accepter un type générique.&lt;br /&gt;
//Elles sont notées par un &amp;#039; et s&amp;#039;appellent généralement &amp;#039;a, puis &amp;#039;b, &amp;#039;c etc.&lt;br /&gt;
//Elles se placent après le &amp;amp; de la référence avec un espace. Par ex:&lt;br /&gt;
&amp;amp;i32        // a reference&lt;br /&gt;
&amp;amp;&amp;#039;a i32     // a reference with an explicit lifetime&lt;br /&gt;
&amp;amp;&amp;#039;a mut i32 // a mutable reference with an explicit lifetime&lt;br /&gt;
//entre elles.&lt;br /&gt;
&lt;br /&gt;
//Alors reprenons notre fonction et donnons lui des annotations de lifetime.&lt;br /&gt;
//On veut dire à Rust : la valeur de retour est valide tant que les 2 paramètres&lt;br /&gt;
//sont valides.&lt;br /&gt;
fn longest&amp;lt;&amp;#039;a&amp;gt;(x: &amp;amp;&amp;#039;a str, y: &amp;amp;&amp;#039;a str) -&amp;gt; &amp;amp;&amp;#039;a str {&lt;br /&gt;
    if x.len() &amp;gt; y.len() {&lt;br /&gt;
        x&lt;br /&gt;
    } else {&lt;br /&gt;
        y&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
//On note le &amp;lt;&amp;#039;a&amp;gt; sur le même principe qu&amp;#039;un type générique &amp;lt;T&amp;gt;.&lt;br /&gt;
//Les annotations ne vont que dans la signature de la fonction.&lt;br /&gt;
//Ici, lors de l&amp;#039;appel, le lifetime concret de la valeur renvoyée sera &lt;br /&gt;
//substituée par &amp;#039;a, qui correspond au scope où se trouveront à la fois x et y,&lt;br /&gt;
//soit le plus petit des 2 lifetimes (lifetime de x et lifetime de y).&lt;br /&gt;
//Ceci fonctionne:&lt;br /&gt;
fn main() {&lt;br /&gt;
    let string1 = String::from(&amp;quot;long string is long&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    {&lt;br /&gt;
        let string2 = String::from(&amp;quot;xyz&amp;quot;);&lt;br /&gt;
        let result = longest(string1.as_str(), string2.as_str());&lt;br /&gt;
        println!(&amp;quot;The longest string is {}&amp;quot;, result);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Ceci ne fonctionne pas car lors du println!, string2 n&amp;#039;existe plus.&lt;br /&gt;
//result ayant le lifetime du plus petit des 2 paramètres, lui non plus n&amp;#039;est&lt;br /&gt;
//plus valide. Cela même si String2 n&amp;#039;est pas la valeur choisie par la fonction.&lt;br /&gt;
fn main() {&lt;br /&gt;
    let string1 = String::from(&amp;quot;long string is long&amp;quot;);&lt;br /&gt;
    let result;&lt;br /&gt;
    {&lt;br /&gt;
        let string2 = String::from(&amp;quot;xyz&amp;quot;);&lt;br /&gt;
        result = longest(string1.as_str(), string2.as_str());&lt;br /&gt;
    }&lt;br /&gt;
    println!(&amp;quot;The longest string is {}&amp;quot;, result);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//En revanche, ceci fonctionnerait parce que le lifetime de y&lt;br /&gt;
//n&amp;#039;as pas de rapport avec le lifetime du renvoi&lt;br /&gt;
fn longest&amp;lt;&amp;#039;a&amp;gt;(x: &amp;amp;&amp;#039;a str, y: &amp;amp;str) -&amp;gt; &amp;amp;&amp;#039;a str {&lt;br /&gt;
    x&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Le même principe peut s&amp;#039;appliquer sur un struct si celui-ci contient une&lt;br /&gt;
//référence.&lt;br /&gt;
//Ici, le lifetime du bras part est relié à celui de la valeur du string&lt;br /&gt;
//à laquelle la slice mise dans part fait référence.&lt;br /&gt;
struct ImportantExcerpt&amp;lt;&amp;#039;a&amp;gt; {&lt;br /&gt;
    part: &amp;amp;&amp;#039;a str,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fn main() {&lt;br /&gt;
    let novel = String::from(&amp;quot;Call me Ishmael. Some years ago...&amp;quot;);&lt;br /&gt;
    let first_sentence = novel.split(&amp;#039;.&amp;#039;).next().expect(&amp;quot;Could not find a &amp;#039;.&amp;#039;&amp;quot;);&lt;br /&gt;
    let i = ImportantExcerpt {&lt;br /&gt;
        part: first_sentence,&lt;br /&gt;
    };&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Ici, j&amp;#039;ai rien compris sur les règles d&amp;#039;elision et les méthodes&lt;br /&gt;
&lt;br /&gt;
//Static lifetime&lt;br /&gt;
//Il existe un lifetime special : &amp;#039;static&lt;br /&gt;
//Il signifie que la référence peut vivre toute la durée du programme.&lt;br /&gt;
//Elle s&amp;#039;applique par défaut aux string litterals.&lt;br /&gt;
let s: &amp;amp;&amp;#039;static str = &amp;quot;I have a static lifetime.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//Le texte est stocké en dur dans le binaire, qui est toujours accessible.&lt;br /&gt;
//Il est très rare qu&amp;#039;utiliser ce lifetime ailleurs soit une bonne idée.&lt;br /&gt;
&lt;br /&gt;
//LES 3 ENSEMBLE&lt;br /&gt;
fn main() {&lt;br /&gt;
    let string1 = String::from(&amp;quot;abcd&amp;quot;);&lt;br /&gt;
    let string2 = &amp;quot;xyz&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    let result = longest_with_an_announcement(&lt;br /&gt;
        string1.as_str(),&lt;br /&gt;
        string2,&lt;br /&gt;
        &amp;quot;Today is someone&amp;#039;s birthday!&amp;quot;,&lt;br /&gt;
    );&lt;br /&gt;
    println!(&amp;quot;The longest string is {}&amp;quot;, result);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
use std::fmt::Display;&lt;br /&gt;
&lt;br /&gt;
fn longest_with_an_announcement&amp;lt;&amp;#039;a, T&amp;gt;(&lt;br /&gt;
    x: &amp;amp;&amp;#039;a str,&lt;br /&gt;
    y: &amp;amp;&amp;#039;a str,&lt;br /&gt;
    ann: T,&lt;br /&gt;
) -&amp;gt; &amp;amp;&amp;#039;a str&lt;br /&gt;
where&lt;br /&gt;
    T: Display,&lt;br /&gt;
{&lt;br /&gt;
    println!(&amp;quot;Announcement! {}&amp;quot;, ann);&lt;br /&gt;
    if x.len() &amp;gt; y.len() {&lt;br /&gt;
        x&lt;br /&gt;
    } else {&lt;br /&gt;
        y&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>Justine</name></author>
	</entry>
</feed>