En résumé, la méthode du trait doit prendre en paramètre un
&Fn(X) -> Y
et non un
Fn(X) -> Y
Sinon, Rust ne peut pas garantir l'exécution de la fonction puisque le trait prendrait possession de la fonction. Or cette closure peut être un pointeur sur fonction, ce qui retirerait la propriété de cette dernière de sa structure.
Code d'exemple
fn fun_test(value: i32, f: &dyn Fn(i32) -> i32) -> i32 {
println!("{}", f(value));
value
}
fn times2(value: i32) -> i32 {
2 * value
}
fn main() {
fun_test(5, ×2);
}
Explication
Il y a trois types possibles de fonctions :
- Fn qui ne peut pas modifier l'objet qu'elle capture.
- FnMut qui peut modifier l'objet qu'elle capture.
- FnOnce la plus restrictive. Ne peut être appelée qu'une seule fois car une fois invoquée elle se consomme elle-même ainsi que l'objet qu'elle capture.
Je suis bluffée ! Les filters des Stream sont toujours plus lents que les boucles classiques en Java.
Le seul moment où les boucles classiques ne sont pas les plus rapides, c'est dans le cas de figure où la taille des collections dépasse les 500 K éléments et que les Parallel Stream sont utilisées à la place des Stream (et que nous sommes sur une architecture multi-cœurs évidemment) ; sinon les Stream perdent à chaque fois.
Vous savez pourquoi Excel ou LibreOffice Calc c'est pourri et que ça ne devrait jamais être utilisé dans un cadre professionnel qui intervient après l'étape du PoC ?
Parce qu'on ne peut pas écrire de tests/TU avec une feuille de calcul !
Ce faisant il n'y a aucun moyen de prouver que les résultats obtenus soient justes. #AmateurismeSur20
D'où toutes ces erreurs récurrentes qui popent tous les mois dans les grands merdia comme le dernier qui de mémoire disant quelque chose du type : la feuille de calcul des britanniques ne gérait pas assez de lignes/colonnes pour encaisser la quantité de données nécessaires aux statistiques du COVID, du coup les chiffres sur lesquels le gouvernement s'appuyait étaient faux et ont eu une conséquence sur la gestion de la crise sanitaire....
Bref, il faut abandonner Excel et les tableurs d'une manière générale dès qu'ils sont utilisés après la phase d'expérimentation/idéation.
In this post we discuss what Java 8 streams are, the most important operations you can perform on them and some best practices of using the streams in your code. Lazy execution, intermediate and terminal operations, parallel streams and so on. Also, you can download and print out 1 page cheat sheet with the most essential information on Java 8 streams!
Un tuto très sympa et très facile à comprendre (pour Roudoudoutte)
Un résumé d'une bonne partie des lambas (Consumer, BiFunction, Function, Predicate) et des pointeurs sur fonctions.
Toujours sur les tutos en Java 8 je vais essayer de vous expliquer les mapper et la méthode .map de l'API Stream.
Définition 'Mapper' :
Objet ou fonction permettant de convertir un élément en un autre élément.
Exemple :
J'ai une liste de String :
List<String> list = ...;
Que je souhaite convertir en ceci :
List<Integer> sizes; // qui contient la taille de chacune des String de la liste précédente.
En vieux Java j'écrirais :
private List<Integer> convert(List<String> strList) {
List<Integer> result = new ArrayList<>(list.size());
for (String str : strList) {
result.add(str.size());
}
return result;
}
En lambda j'écrirai :
private List<Integer> convert(List<String> strList) {
return strList.stream().map(str -> str.size()).toList();
}
Et votre mapper c'est cette petite lamdba 'str -> str.size()' qui sera appliquée à chaque élément de la liste un par un.
Comme pour certains termes financiers, je posterai quelques définitions sur les lambdas.
Prédicat :
=> Fonction qui retourne un booléen.
Les prédicats sont très utilisés dans les filtres, par exemple vous souhaitez parcourir une collection et ne retourner dans une liste que les personnes étant majeures, alors vous créerez une lambda prenant en paramètre une personne et qui retournera true si celle-ci est majeure ou false sinon.
Exemple :
-
Prédicat sans paramètres :
( ) -> true
-
Prédicat sans paramètres mais où l'on spécifie explicitement le return (qui est facultatif en PF) :
( ) -> { return true; }
-
Prédicat avec un paramètre et le return :
(person) -> { return person.isMale(); }
-
Prédicat avec deux paramètres :
(persA, persB) -> { Object.equals(persA, persB); }
-
Prédicat avec deux paramètres, le return et dont on spécifie le type des paramètres :
(Person persA, Person persB) -> { return Object.equals(persA, persB); }
Je poursuis ma migration vers le fonctionnel sur Java 8 avec un petit tuto sur les stream et les map-reduce. Le tout est guidé par une multitude de petits exemples simples.
Je découvre le blog de Jean-Christophe Gay. Très sympa et assez complet sur Java 8.
Attention : si vous ne vous êtes toujours pas mis aux lambdas, aux Clojures et aux Predicats, vous allez avoir du mal à vous revendre dans l'univers Java. Début 2016, cela deviendra indispensable !
P.S : vous savez que je déteste la programmation fonctionnelle car l'inférence de type permet de produire bien trop souvent un code immaintenable, cependant, utilisée avec BEAUCOUP de parcimonie, elle permet de factoriser énormément de code technique et éviter les doublons. Bref, je m'y suis mise, ce n'est pas pour rien.
Les lambda & Clojure de Java 8
Vu que je suis obligée de faire de la programmation fonctionnelle (avec inférence de type, ce que je déteste au plus haut point), je vais poster une série de tutos à ce sujet.