Un regard sur Passer par les yeux d'un développeur .NET. Semaine # 1

Bonjour Ă  tous!

Je m'appelle Lex et je suis l'hÎte de la chaßne YouTube " IT Beard ". Et je suis un associé de 6 ans. Récemment, j'avais envie d'aller au-delà de ma technologie de base (C # /. NET), et de comprendre l'essence du paradoxe Blob . J'ai fermement décidé de m'essayer dans une autre langue, et le choix s'est fait par hasard sur Go.

Afin d'acquérir des connaissances de maniÚre structurée, je me suis inscrit à un cours de mail.ru, que vous pouvez trouver ici: https://www.coursera.org/learn/golang-webservices-1 . En fait, ce que j'ai appris de la premiÚre semaine de formation dans ce cours sera discuté plus loin. C'est parti!


Je vais commencer par une petite intro sur la langue. Go Ă©tait dĂ©jĂ  dĂ©veloppĂ© Ă  l'Ă©poque des processeurs multicƓurs (2007-2009), donc tout est trĂšs bien ici avec la parallĂ©lisation du travail sur les cƓurs. De plus, la langue fonctionne trĂšs bien avec les demandes concurrentielles (simultanĂ©es). En gĂ©nĂ©ral, une recherche pour toutes sortes de services Web et de systĂšmes Web chargĂ©s. Exactement ce dont j'ai besoin, car j'ai dĂ©veloppĂ© des API Web (API Web) ces derniĂšres annĂ©es.

Commencer


Pour travailler avec la langue, il suffit d'installer le progiciel «Go tools» de 118 Mo et vous pouvez commencer à coder.

Les scripts ont l' extension * .go et sont exécutés par la commande go sur la ligne de commande (je suis un adhérent de la ligne de commande Windows). La commande gofmt place tous les espaces d'indentation et crée des bonbons à partir du fichier (embellisseur de code hors de la boßte). Comme dans mon sous-réseau préféré, dans Go, l'exécution du programme commence par la méthode principale .
Une fonctionnalité intéressante a immédiatement attiré mon attention - vous ne pouvez pas mettre de point-virgule à la fin de la ligne :)

Go est un autre langage (avec python, c #, php, js, ts et autres), qui est pratique pour travailler avec VSCode. VSCode lui-mĂȘme fournit absolument tous les packages et dĂ©pendances nĂ©cessaires lors de l'Ă©criture du code. Lors de l'enregistrement de l'IDE, veuillez exĂ©cuter gofmt pour vous et rendre le code encore plus beau.

Variables


Tout est familier ici: il existe de nombreux types diffĂ©rents, il existe des valeurs par dĂ©faut. D'inhabituel pour un donateur, le mot-clĂ© var signifie que la variable ira plus loin, et le type de la variable peut ĂȘtre dĂ©clarĂ© ou pas dĂ©jĂ  aprĂšs le nom de la variable. Exceptionnellement.

En gĂ©nĂ©ral, il existe de nombreuses façons de dĂ©clarer et d'initialiser des variables. Vous pouvez mĂȘme affecter des valeurs Ă  plusieurs variables, sĂ©parĂ©es par des virgules, sur la mĂȘme ligne. Et en passant, il n'y a pas de transtypages implicites.

Et Go a également un opérateur " : = ", qui vous permet de déclarer et d'initialiser immédiatement de nouvelles variables (et presque toujours uniquement de nouvelles). Salut Pascal;)

Vue d'enregistrement:

perem1, perem2 := 2, 3 
soit crée deux nouvelles variables, soit en crée une, et la seconde affecte simplement une nouvelle valeur. Cela signifie que si les deux variables existent déjà, cela ne fonctionnera pas et vous obtiendrez une erreur, disent-ils utiliser l'affectation habituelle. Opérateur : = doit créer quelque chose :)

Il y a aussi un faux drÎle - le caractÚre de soulignement "_". Cela signifie l'absence d'une variable, quelque chose comme ça :) (dans les objets tranchants, comme il s'est avéré, c'est aussi: https://docs.microsoft.com/en-us/dotnet/csharp/discards )

image

Moment amusant avec des chaßnes: le décompte standard de la longueur de chaßne d'une chaßne len (str) compte les octets , et en UTF8 un caractÚre peut peser plus. Pour compter les caractÚres appelés runes , vous devez utiliser la méthode utf8.RuneCountInString (str) du package «utf8». Et, et pourtant - nous ne changeons pas les lignes (comme dans votre préféré).

Constantes


Les constantes peuvent ĂȘtre dĂ©clarĂ©es par lots. Les constantes ont un type intĂ©ressant, ou quelque chose comme ça - iota . Je l'appellerai Jopta. Jopta vous permet de faire certaines constantes sur la base d'autres, quelque chose comme un itĂ©rateur pour les constantes (quelque chose qui rappelle le rendement d'un sous-rĂ©seau).

Et pourtant, les constantes ne peuvent pas ĂȘtre saisies. Pour de telles constantes, le compilateur dĂ©cide de quel type elles sont au bon moment. IdĂ©alement, ce qui est dĂ©jĂ  lĂ .



Pointeurs


Oui oui Il y a des indications ici, mais cela ne semble pas trÚs effrayant. Ils disent qu'ils ne sont pas numérotés, et vous ne pouvez pas obtenir le prochain pointeur en ajoutant un pair au pointeur. Ici, c'est un peu comme une variable qui stocke un lien vers une autre variable (jusqu'à présent, je l'ai en quelque sorte compris).

Le pointeur est spécifié via un esperant ou la nouvelle méthode (type) (pour obtenir un pointeur vers un type, pas une variable):



Si vous accédez directement au pointeur, le lien change. Et si par l'opérateur " * ", alors la valeur de la variable qui se trouve derriÚre le pointeur (vers lequel il pointe) change. En général, ce n'est pas encore trÚs clair, mais alors, disent-ils, ce sera plus clair.

Tableaux


La taille du tableau fait partie du type de données! Ainsi, les tableaux de différentes dimensions sont en fait différents types de données et ne sont pas compatibles.



Mais que faut-il pour les tableaux s'ils sont si secs et immuables (ils ne peuvent pas ĂȘtre modifiĂ©s pendant l'exĂ©cution). Par consĂ©quent, nous avons proposĂ© de telles tranches (tranches) basĂ©es sur des tableaux.



Une tranche a une longueur et une capacitĂ© . Cela m'a rappelĂ© un peu le type de donnĂ©es nvarchar de SQL. C'est-Ă -dire vous pouvez allouer de l'espace mĂ©moire (allocation de mĂ©moire) Ă  vos baies, mais y mettre des baies de n'importe quelle longueur (jusqu'Ă  la capacitĂ©). Bref, la chose est intĂ©ressante, il faut s'y habituer. Pour une utilisation pratique des tranches, il existe toutes sortes de mĂ©thodes telles que make (), append (), len (), cap () et, bien sĂ»r, d'autres. À partir d'une tranche (tranche), vous pouvez obtenir lĂ©gĂšrement une sous-tranche (tranche de tranche). Et en passant, append () Ă©tend la capacitĂ© de la tranche.

Si la sous-tranche est égale à la tranche, alors en fait, ils se réfÚreront à un morceau de mémoire. Et en conséquence, un changement de la valeur dans une tranche entraßnera un changement dans la deuxiÚme tranche. Mais si l'un d'eux est développé via append () , un nouveau morceau de mémoire sera alloué.
Bref, tout est sérieux avec la mémoire :)

Carte, table de hachage, tableau associatif


Tout cela est le mĂȘme. Allez sur des tables de hachage pour des recherches de clĂ©s rapides. InitialisĂ© comme suit:



Vous pouvez créer des sous-tables (Map Map), etc. (n'importe quel niveau d'imbrication, un peu comme). Il existe une valeur par défaut qui renvoie des clés inexistantes. Il est tiré du type de clé (pour bool, puis false). Pour savoir si une variable est retournée par défaut, c'est-à-dire que la clé est manquante - utilisez la clé pour l'existence de la clé (chose intéressante):



Structures de contrĂŽle


Il y a un if-else. Un peu plus intéressant que dans les objets tranchants, car vous pouvez utiliser les conditions d'initialisation pour if.

Il y a un swith-case. Les pauses n'ont pas besoin d'ĂȘtre dĂ©finies, et c'est une diffĂ©rence. Inversion de la logique) Si vous souhaitez Ă©galement vĂ©rifier la condition suivante, vous devez Ă©crire fallthrough .

Il y a pour. Et tout cela avec des cycles.



Avec tranche itérative plus ludique (opérateur de plage):



Et mĂȘme par carte de hachage, vous pouvez itĂ©rer (bien que la sĂ©quence soit souvent diffĂ©rente, car la carte n'est pas directionnelle):



Pour le type, la plage de chaĂźnes itĂšre sur les runes, pas sur les octets.

Les fonctions


Déclaré via le mot clé func . De plus, l'inversion de la logique est à nouveau comparée au sous-réseau - les paramÚtres d'entrée sont indiqués en premier, puis le type de la valeur de retour (vous pouvez immédiatement le nommer).

Les fonctions peuvent renvoyer plusieurs résultats , tout comme les tuples dans un sous - réseau .

Les valeurs nommées renvoyées par la fonction sont initialisées par défaut avec des valeurs par défaut pour le type.

Et pourtant, vous pouvez crĂ©er des fonctions variables qui ont un nombre illimitĂ© de paramĂštres d'entrĂ©e du mĂȘme type (comme param dans le sous-rĂ©seau). Et puis un type spĂ©cifique de tranche vient Ă  l'entrĂ©e de la fonction.

Les fonctions peuvent avoir des noms ou ĂȘtre sans nom - anonymes . Et ils peuvent ĂȘtre appelĂ©s, peuvent ĂȘtre affectĂ©s Ă  des variables. Cela ressemble Ă  JavaScript. Vous pouvez mĂȘme crĂ©er des types basĂ©s sur des fonctions! Les fonctions peuvent ĂȘtre passĂ©es comme paramĂštres (lire les dĂ©lĂ©guĂ©s du sous-rĂ©seau)

Il y a mĂȘme une fermeture (uuuh, effrayante)! Vous pouvez atteindre les variables de la fonction en dehors de celle-ci (lire, dans la fonction parent). Ce sont les tartes.

Vous pouvez déclarer l' exécution différée des fonctions . Grùce au mot clé defer, cela se fait. C'est-à-dire les fonctions différées sont exécutées à la fin de la fonction dans laquelle elles sont déclarées, dans l'ordre inverse de la déclaration de ces fonctions différées. Ici. De plus, l'initialisation des arguments des fonctions différées se produit lorsque le bloc de report est déclaré . C'est important, surtout si une autre fonction est prise comme argument - elle sera exécutée beaucoup plus tÎt que prévu!

PANIQUE! Go a une telle fonction - panic () . C’est comme la remise en jeu, mais pire. Cette fonction arrĂȘte l'exĂ©cution du programme. Mais cette mĂȘme panique peut ĂȘtre traitĂ©e par report, car elle est exĂ©cutĂ©e de n'importe quelle façon Ă  la fin de la fonction, mĂȘme aprĂšs une panique. Et pourtant - panique, ce n'est pas un essai. C'est pire!

Structures (quasi-objets)


Le go n'est pas tout Ă  fait un langage de paradigme OOP. Mais il y a des choses comme les structures . Si vous ĂȘtes du monde du sous-rĂ©seau, vous savez que nous avons Ă©galement des structures - ce sont des mappages d'objets qui peuvent ĂȘtre stockĂ©s sur la pile (types de valeurs). Dans Go, la structure est en quelque sorte le seul moyen de faire quelque chose comme un objet. Je ne peux pas encore parler des types de valeur, mais la nature de l'interaction avec les structures est trĂšs similaire Ă  celle dĂ©taillĂ©e.

Chaque structure est essentiellement un type distinct et peut avoir un ensemble de propriétés de types spécifiques (y compris le type d'une autre structure ou type de fonction):



De plus, un certain mécanisme d'héritage direct des objets du sous-réseau est vu ici. Dans l'image ci-dessus, la structure de compte est imbriquée avec la structure de personne . Cela signifie que tous les champs de Personne seront disponibles dans une variable de type Compte . Si les noms de propriété coïncident (dans l'exemple ci-dessus Id, Name ), il n'y aura pas de conflit, mais la valeur d'un champ supérieur sera prise:



Les méthodes


Oui, il n'y a pas seulement la similitude des objets, mais aussi des méthodes. Presque OOP :) Une méthode est une fonction liée à un type spécifique (par exemple, à une structure). Une méthode diffÚre d'une fonction dans une déclaration: aprÚs le mot clé func , entre parenthÚses, vous devez spécifier le type auquel appartient cette méthode et le rÎle de passer une variable de ce type. Quel est le rÎle? Si vous mettez un astérisque devant le type, la variable sera transmise par référence (rappelez-vous les pointeurs, elle était là aussi), et en conséquence, à l'intérieur de la méthode, nous travaillerons avec un type spécifique, et non une copie de celui-ci.



D'aprÚs l'image ci-dessus, nous pouvons conclure que UpdateName n'a pas de sens, car il modifie la copie de la structure et non l'original. Et cette copie ne revient pas. Alors que SetName va changer la structure d'origine (grùce à l'astérisque et en passant par référence).

Les méthodes dans les structures sont héritées (et selon les rÚgles d'héritage de propriété), c'est-à-dire la structure parente a accÚs à toutes les méthodes imbriquées dans ses structures.

D'autres types peuvent avoir des mĂ©thodes, pas seulement des structures. Cela peut ressembler Ă  des mĂ©thodes d'extension de sous-rĂ©seau, mais non. Les mĂ©thodes dans Go ne peuvent ĂȘtre créées que pour les types locaux, c'est-Ă -dire types qui sont dĂ©clarĂ©s dans ce package (Ă  propos des packages un peu plus loin).

Packages, portée, espaces de noms


Je viens de rĂ©aliser que Go n'a pas NEIMSPACE! GĂ©nĂ©ralement! Je m'en suis rendu compte quand, aprĂšs la compilation, une erreur est sortie, ils disent que dans un dossier j'ai deux fichiers avec la mĂ©thode principale. Il s'avĂšre qu'au stade de la compilation, tout, depuis papa, semble ĂȘtre collĂ© ensemble dans une seule toile! Un dossier est en fait un espace de noms. C'est tellement magique, camarades :)

Voici, en passant, ce que dit le dock:



Remarque pour vous-mĂȘme: fumez un quai
Et voici un autre petit article dans le sujet: https://www.callicoder.com/golang-packages/#the-main-package-and-main-function

Ainsi, disent-ils, la structure de dossier de base ressemble Ă :


bin - binaires compilés
pkg - fichiers d'objets temporaires
src - sources
Les packages font référence au nom du dossier dans lequel se trouvent les fichiers de packages. Oui, un package peut contenir de nombreux fichiers importés les uns dans les autres.

Autre rĂšgle intĂ©ressante: les fonctions, propriĂ©tĂ©s, variables et constantes commençant par une majuscule peuvent ĂȘtre utilisĂ©es en dehors du package , c'est-Ă -dire ĂȘtre importĂ© . Tout avec une petite lettre est utilisĂ© uniquement Ă  l'intĂ©rieur du colis. Un analogue des modificateurs d'accĂšs du sous-rĂ©seau.

Le mot-clé d' importation fonctionne dans un fichier, pas dans un package.

Interfaces


Les interfaces ici sont intĂ©ressantes. Nous n'avons pas besoin d'hĂ©riter des interfaces de nos structures. Il suffit que la structure, qui vient comme paramĂštre d'entrĂ©e d'une certaine mĂ©thode qui prend un type d'interface, implĂ©mente les mĂ©thodes de cette interface. Et il n'y a aucun problĂšme. C'est-Ă -dire les mĂ©thodes d'interface ne doivent pas nĂ©cessairement ĂȘtre implĂ©mentĂ©es par la structure. Mais la structure doit contenir l'implĂ©mentation de toutes les mĂ©thodes requises dans une fonction particuliĂšre, oĂč le type d'interface est utilisĂ© comme paramĂštre d'entrĂ©e.

Il s'avÚre que, contrairement à Go, l'interface est une caractéristique de la fonction dans laquelle elle est utilisée, et non une caractéristique d'une structure spécifique (objet).

Si c'est encore plus simple, alors la logique est la suivante: vous n'avez pas besoin d'ĂȘtre capable de charlatan pour ĂȘtre un canard. Si vous savez charlatan, alors vous ĂȘtes probablement un canard :)
Et au fait, si votre structure implĂ©mente toutes les mĂ©thodes d'une interface, alors cette structure peut ĂȘtre affectĂ©e comme valeurs de la variable de l'interface implĂ©mentĂ©e . Quelque chose comme ça :)

Type boĂźtier de commutateur


Go a un boßtier de commutation spécial qui peut fonctionner en fonction du type entrant. Chose cool:



Soit dit en passant, voici comment vous pouvez convertir un type en un autre (par exemple, un type d'interface en un type de structure afin d'obtenir des champs de structure qui ne sont pas accessibles depuis l'interface):



ok - signe booléen que la conversion a réussi. Nous avons déjà rencontré les signes :)

L'interface vide est la bĂȘte du monde de Go. Cela peut prendre n'importe quel type. Quelque chose comme dynamique ou Object in. Par exemple, il est utilisĂ© dans fmt.Println () et des fonctions similaires qui utilisent une interface vide dans l'implĂ©mentation.

Les interfaces peuvent ĂȘtre intĂ©grĂ©es les unes aux autres, et ainsi faire la composition des interfaces (ce qui est dit dans la lettre I (sĂ©grĂ©gation des interfaces) des principes SOLID )

Les tests


Dans Go, toutes les fonctions de test commencent par le mot Test et l'entrée du test du module de test est acceptée. Les fichiers sont nommés par le nom du fichier de test + mot _test ( main_test.go - teste le fichier main.go ). De plus, les tests et les fichiers de test sont dans un seul paquet!



Épilogue


C’est tout! Merci de votre attention et je suis prĂȘt Ă  discuter des problĂšmes dans les commentaires. Je vous retrouve dans les notes suivantes de mes cours!

PS Vous pouvez regarder toutes mes promenades de code sur cette semaine de formation sur github

Source: https://habr.com/ru/post/fr455830/


All Articles