From d00c5e67d04d83d647746836872d3c1e1ed74d0b Mon Sep 17 00:00:00 2001 From: fnscoder Date: Wed, 4 Oct 2017 21:53:03 -0300 Subject: fix names in pt-br --- pt-br/amd-pt.html.markdown | 218 ++++++++++ pt-br/amd.html.markdown | 218 ---------- pt-br/bf-pt.html.markdown | 86 ++++ pt-br/bf.html.markdown | 86 ---- pt-br/csharp-pt.html.markdown | 896 ++++++++++++++++++++++++++++++++++++++++++ pt-br/csharp.html.markdown | 896 ------------------------------------------ pt-br/elixir-pt.html.markdown | 412 +++++++++++++++++++ pt-br/elixir.html.markdown | 412 ------------------- 8 files changed, 1612 insertions(+), 1612 deletions(-) create mode 100644 pt-br/amd-pt.html.markdown delete mode 100644 pt-br/amd.html.markdown create mode 100644 pt-br/bf-pt.html.markdown delete mode 100644 pt-br/bf.html.markdown create mode 100644 pt-br/csharp-pt.html.markdown delete mode 100644 pt-br/csharp.html.markdown create mode 100644 pt-br/elixir-pt.html.markdown delete mode 100644 pt-br/elixir.html.markdown (limited to 'pt-br') diff --git a/pt-br/amd-pt.html.markdown b/pt-br/amd-pt.html.markdown new file mode 100644 index 00000000..38c1f70f --- /dev/null +++ b/pt-br/amd-pt.html.markdown @@ -0,0 +1,218 @@ +--- +category: tool +tool: amd +contributors: + - ["Frederik Ring", "https://github.com/m90"] +translators: + - ["Felipe Tarijon", "http://nanoincub.com/"] +lang: pt-br +filename: learnamd-pt.js +--- + +## Começando com AMD + +A API de Definição de Módulos Assíncrona **Asynchronous Module Definition** +especifica um mecanismo para definição de módulos em JavaScript para os quais o +módulo e suas dependências podem ser carregados de forma assíncrona. Isso é +particularmente bem adequado para o ambiente do browser onde o carregamento de +módulos de forma síncrona fica sujeito a problemas de performance, usabilidade, +debugging e problemas de acesso em requisições cross-domain. + +### Conceito básico +```javascript +// O básico da API de AMD consiste de nada mais que dois métodos: `define` e `require` +// e isso é tudo sobre a definição de módulo e consumo: +// `define(id?, dependências?, factory)` define um módulo +// `require(dependências, callback)` importa uma série de dependências e +// consome elas no callback passado como parâmetro. + +// Vamos começar usando o define para definir um novo módulo +// que não tem dependências. Nós vamos fazer isso passando um nome +// e uma função factory para definir: +define('awesomeAMD', function(){ + var isAMDAwesome = function(){ + return true; + }; + // O valor retornado da função de factory do módulo é + // o que os outros módulos ou chamadas de require irão + // receber quando requisitarem nosso módulo `awesomeAMD`. + // O valor exportado pode ser qualquer coisa, (construtor) funções, + // objetos, primitives, até mesmo undefined (apesar de que não irão ajudar muito). + return isAMDAwesome; +}); + +// Agora, vamos definir outro módulo que depende do nosso módulo `awesomeAMD`. +// Perceba que existe um argumento adicional definindo nossas dependências do +// módulo agora: +define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ + // dependências serão passadas como argumentos da factory + // na ordem que elas forem especificadas + var tellEveryone = function(){ + if (awesomeAMD()){ + alert('Isso é tãaaao loko!'); + } else { + alert('Bem estúpido, né não?'); + } + }; + return tellEveryone; +}); + +// Agora que nós sabemos como usar o define, vamos usar o `require` para +// começar nosso programa. A assinatura do `require` é `(arrayDedependências, callback)`. +require(['loudmouth'], function(loudmouth){ + loudmouth(); +}); + +// Para fazer esse tutorial executável, vamos implementar uma versão muito básica +// (não-assíncrona) de AMD bem aqui nesse lugar: +function define(nome, deps, factory){ + // perceba como os módulos sem dependências são manipulados + define[nome] = require(factory ? deps : [], factory || deps); +} + +function require(deps, callback){ + var args = []; + // primeiro vamos recuperar todas as dependências necessárias + // pela chamada requerida + for (var i = 0; i < deps.length; i++){ + args[i] = define[deps[i]]; + } + // corresponder todas as dependências da função de callback + return callback.apply(null, args); +} +// você pode ver esse código em ação aqui: http://jsfiddle.net/qap949pd/ +``` + +### Uso na vida real com require.js + +Em contraste com o exemplo introdutório, `require.js` (a biblioteca mais popular de AMD) na verdade implementa o **A** do **AMD**, permitindo que você carregue os módulos e suas +dependências via XHR: + +```javascript +/* file: app/main.js */ +require(['modules/algumaClasse'], function(AlgumaClasse){ + // o callback é deferido até que a dependencia seja carregada + var coisa = new AlgumaClasse(); +}); +console.log('Então aqui estamos nós, esperando!'); // isso vai rodar primeiro +``` + +Por convenção, você geralmente guarda um módulo em um arquivo. `require.js` pode resolver nome de módulos baseado no caminho das pastas, então você não precisa nomear os seus módulos, mas sim simplesmente referenciar eles usando sua origem. No exemplo `algumaClasse` é adotado a pasta `modules`, relativa a configuração da sua `baseUrl`: + +* app/ + * main.js + * modules/ + * algumaClasse.js + * algunsHelpers.js + * ... + * daos/ + * coisas.js + * ... + +Isso significa que nós podemos definir `algumaClasse` sem especificar o id de um módulo: + +```javascript +/* arquivo: app/modules/algumaClasse.js */ +define(['daos/coisas', 'modules/algunsHelpers'], function(coisasDao, helpers){ + // definição de módulo, claro, irá acontecer também de forma assíncrona + function AlgumaClasse(){ + this.metodo = function(){/**/}; + // ... + } + return AlgumaClasse; +}); +``` +Para alterar o comportamento padrão de mapeamento de caminho de pastas utilize +`requirejs.config(configObj)` em seu `main.js`: + +```javascript +/* arquivo: main.js */ +requirejs.config({ + baseUrl : 'app', + paths : { + // você pode também carregar módulos de outros locais + jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}); +require(['jquery', 'coolLibFromBower', 'modules/algunsHelpers'], function($, coolLib, helpers){ + // um arquivo `main` precisa chamar o require pelo menos uma vez, + // caso contrário, o código jamais rodará + coolLib.facaAlgoDoidoCom(helpers.transform($('#foo'))); +}); +``` +Apps baseados em `require.js` geralmente terão u´m único ponto de acesso (`main.js`) que é passado à tag script do `require.js` como um data-attribute. Ele vai ser automaticamente carregado e executado com o carregamento da página: + +```html + + + + Umas 100 tags de script? Nunca mais! + + + + + +``` + +### Otimizando um projeto inteiro utilizando r.js + +Muitas pessoas preferem usar AMD para sanar a organização do código durante o desenvolvimento, mas continuam querendo colocar um único arquivo de script em produção ao invés de realizarem centenas de requisições XHRs no carregamento da página. + +`require.js` vem com um script chamado `r.js` (que você vai provavelmente rodar em node.js, embora Rhino suporte também) que você pode analisar o gráfico de dependências de seu projeto, e fazer em um único arquivo contendo todos os seus módulos (corretamente nomeados), minificados e prontos para serem consumidos. + +Instale-o utilizando `npm`: +```shell +$ npm install requirejs -g +``` + +Agora você pode alimentá-lo com um arquivo de configuração: +```shell +$ r.js -o app.build.js +``` + +Para o nosso exemplo acima a configuração pode ser essa: +```javascript +/* file : app.build.js */ +({ + name : 'main', // nome do ponto de acesso + out : 'main-built.js', // nome o arquivo para gravar a saída + baseUrl : 'app', + paths : { + // `empty:` fala para o r.js que isso ainda deve ser baixado da CDN, usando + // o local especificado no `main.js` + jquery : 'empty:', + coolLibFromBower : '../bower_components/cool-lib/coollib' + } +}) +``` + +Para usar o arquivo gerado, em produção, simplesmente troque o `data-main`: +```html + +``` + +Uma incrível e detalhada visão geral [de build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponível no repositório do GitHub. + +### Tópicos não abordados nesse tutorial +* [Plugins de carregamento / transforms](http://requirejs.org/docs/plugins.html) +* [CommonJS style carregamento e exportação](http://requirejs.org/docs/commonjs.html) +* [Configuração avançada](http://requirejs.org/docs/api.html#config) +* [Shim configuration (carregando módulos sem AMD)](http://requirejs.org/docs/api.html#config-shim) +* [Carregando e otimizando CSS com require.js](http://requirejs.org/docs/optimization.html#onecss) +* [Usando almond.js para builds](https://github.com/jrburke/almond) + +### Outras leituras: + +* [Especificação oficial](https://github.com/amdjs/amdjs-api/wiki/AMD) +* [Por quê AMD?](http://requirejs.org/docs/whyamd.html) +* [Universal Module Definition](https://github.com/umdjs/umd) + +### Implementações: + +* [require.js](http://requirejs.org) +* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) +* [cujo.js](http://cujojs.com/) +* [curl.js](https://github.com/cujojs/curl) +* [lsjs](https://github.com/zazl/lsjs) +* [mmd](https://github.com/alexlawrence/mmd) diff --git a/pt-br/amd.html.markdown b/pt-br/amd.html.markdown deleted file mode 100644 index 38c1f70f..00000000 --- a/pt-br/amd.html.markdown +++ /dev/null @@ -1,218 +0,0 @@ ---- -category: tool -tool: amd -contributors: - - ["Frederik Ring", "https://github.com/m90"] -translators: - - ["Felipe Tarijon", "http://nanoincub.com/"] -lang: pt-br -filename: learnamd-pt.js ---- - -## Começando com AMD - -A API de Definição de Módulos Assíncrona **Asynchronous Module Definition** -especifica um mecanismo para definição de módulos em JavaScript para os quais o -módulo e suas dependências podem ser carregados de forma assíncrona. Isso é -particularmente bem adequado para o ambiente do browser onde o carregamento de -módulos de forma síncrona fica sujeito a problemas de performance, usabilidade, -debugging e problemas de acesso em requisições cross-domain. - -### Conceito básico -```javascript -// O básico da API de AMD consiste de nada mais que dois métodos: `define` e `require` -// e isso é tudo sobre a definição de módulo e consumo: -// `define(id?, dependências?, factory)` define um módulo -// `require(dependências, callback)` importa uma série de dependências e -// consome elas no callback passado como parâmetro. - -// Vamos começar usando o define para definir um novo módulo -// que não tem dependências. Nós vamos fazer isso passando um nome -// e uma função factory para definir: -define('awesomeAMD', function(){ - var isAMDAwesome = function(){ - return true; - }; - // O valor retornado da função de factory do módulo é - // o que os outros módulos ou chamadas de require irão - // receber quando requisitarem nosso módulo `awesomeAMD`. - // O valor exportado pode ser qualquer coisa, (construtor) funções, - // objetos, primitives, até mesmo undefined (apesar de que não irão ajudar muito). - return isAMDAwesome; -}); - -// Agora, vamos definir outro módulo que depende do nosso módulo `awesomeAMD`. -// Perceba que existe um argumento adicional definindo nossas dependências do -// módulo agora: -define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ - // dependências serão passadas como argumentos da factory - // na ordem que elas forem especificadas - var tellEveryone = function(){ - if (awesomeAMD()){ - alert('Isso é tãaaao loko!'); - } else { - alert('Bem estúpido, né não?'); - } - }; - return tellEveryone; -}); - -// Agora que nós sabemos como usar o define, vamos usar o `require` para -// começar nosso programa. A assinatura do `require` é `(arrayDedependências, callback)`. -require(['loudmouth'], function(loudmouth){ - loudmouth(); -}); - -// Para fazer esse tutorial executável, vamos implementar uma versão muito básica -// (não-assíncrona) de AMD bem aqui nesse lugar: -function define(nome, deps, factory){ - // perceba como os módulos sem dependências são manipulados - define[nome] = require(factory ? deps : [], factory || deps); -} - -function require(deps, callback){ - var args = []; - // primeiro vamos recuperar todas as dependências necessárias - // pela chamada requerida - for (var i = 0; i < deps.length; i++){ - args[i] = define[deps[i]]; - } - // corresponder todas as dependências da função de callback - return callback.apply(null, args); -} -// você pode ver esse código em ação aqui: http://jsfiddle.net/qap949pd/ -``` - -### Uso na vida real com require.js - -Em contraste com o exemplo introdutório, `require.js` (a biblioteca mais popular de AMD) na verdade implementa o **A** do **AMD**, permitindo que você carregue os módulos e suas -dependências via XHR: - -```javascript -/* file: app/main.js */ -require(['modules/algumaClasse'], function(AlgumaClasse){ - // o callback é deferido até que a dependencia seja carregada - var coisa = new AlgumaClasse(); -}); -console.log('Então aqui estamos nós, esperando!'); // isso vai rodar primeiro -``` - -Por convenção, você geralmente guarda um módulo em um arquivo. `require.js` pode resolver nome de módulos baseado no caminho das pastas, então você não precisa nomear os seus módulos, mas sim simplesmente referenciar eles usando sua origem. No exemplo `algumaClasse` é adotado a pasta `modules`, relativa a configuração da sua `baseUrl`: - -* app/ - * main.js - * modules/ - * algumaClasse.js - * algunsHelpers.js - * ... - * daos/ - * coisas.js - * ... - -Isso significa que nós podemos definir `algumaClasse` sem especificar o id de um módulo: - -```javascript -/* arquivo: app/modules/algumaClasse.js */ -define(['daos/coisas', 'modules/algunsHelpers'], function(coisasDao, helpers){ - // definição de módulo, claro, irá acontecer também de forma assíncrona - function AlgumaClasse(){ - this.metodo = function(){/**/}; - // ... - } - return AlgumaClasse; -}); -``` -Para alterar o comportamento padrão de mapeamento de caminho de pastas utilize -`requirejs.config(configObj)` em seu `main.js`: - -```javascript -/* arquivo: main.js */ -requirejs.config({ - baseUrl : 'app', - paths : { - // você pode também carregar módulos de outros locais - jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', - coolLibFromBower : '../bower_components/cool-lib/coollib' - } -}); -require(['jquery', 'coolLibFromBower', 'modules/algunsHelpers'], function($, coolLib, helpers){ - // um arquivo `main` precisa chamar o require pelo menos uma vez, - // caso contrário, o código jamais rodará - coolLib.facaAlgoDoidoCom(helpers.transform($('#foo'))); -}); -``` -Apps baseados em `require.js` geralmente terão u´m único ponto de acesso (`main.js`) que é passado à tag script do `require.js` como um data-attribute. Ele vai ser automaticamente carregado e executado com o carregamento da página: - -```html - - - - Umas 100 tags de script? Nunca mais! - - - - - -``` - -### Otimizando um projeto inteiro utilizando r.js - -Muitas pessoas preferem usar AMD para sanar a organização do código durante o desenvolvimento, mas continuam querendo colocar um único arquivo de script em produção ao invés de realizarem centenas de requisições XHRs no carregamento da página. - -`require.js` vem com um script chamado `r.js` (que você vai provavelmente rodar em node.js, embora Rhino suporte também) que você pode analisar o gráfico de dependências de seu projeto, e fazer em um único arquivo contendo todos os seus módulos (corretamente nomeados), minificados e prontos para serem consumidos. - -Instale-o utilizando `npm`: -```shell -$ npm install requirejs -g -``` - -Agora você pode alimentá-lo com um arquivo de configuração: -```shell -$ r.js -o app.build.js -``` - -Para o nosso exemplo acima a configuração pode ser essa: -```javascript -/* file : app.build.js */ -({ - name : 'main', // nome do ponto de acesso - out : 'main-built.js', // nome o arquivo para gravar a saída - baseUrl : 'app', - paths : { - // `empty:` fala para o r.js que isso ainda deve ser baixado da CDN, usando - // o local especificado no `main.js` - jquery : 'empty:', - coolLibFromBower : '../bower_components/cool-lib/coollib' - } -}) -``` - -Para usar o arquivo gerado, em produção, simplesmente troque o `data-main`: -```html - -``` - -Uma incrível e detalhada visão geral [de build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponível no repositório do GitHub. - -### Tópicos não abordados nesse tutorial -* [Plugins de carregamento / transforms](http://requirejs.org/docs/plugins.html) -* [CommonJS style carregamento e exportação](http://requirejs.org/docs/commonjs.html) -* [Configuração avançada](http://requirejs.org/docs/api.html#config) -* [Shim configuration (carregando módulos sem AMD)](http://requirejs.org/docs/api.html#config-shim) -* [Carregando e otimizando CSS com require.js](http://requirejs.org/docs/optimization.html#onecss) -* [Usando almond.js para builds](https://github.com/jrburke/almond) - -### Outras leituras: - -* [Especificação oficial](https://github.com/amdjs/amdjs-api/wiki/AMD) -* [Por quê AMD?](http://requirejs.org/docs/whyamd.html) -* [Universal Module Definition](https://github.com/umdjs/umd) - -### Implementações: - -* [require.js](http://requirejs.org) -* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) -* [cujo.js](http://cujojs.com/) -* [curl.js](https://github.com/cujojs/curl) -* [lsjs](https://github.com/zazl/lsjs) -* [mmd](https://github.com/alexlawrence/mmd) diff --git a/pt-br/bf-pt.html.markdown b/pt-br/bf-pt.html.markdown new file mode 100644 index 00000000..52a5269e --- /dev/null +++ b/pt-br/bf-pt.html.markdown @@ -0,0 +1,86 @@ +--- +language: bf +filename: learnbf-pt.bf +contributors: + - ["Prajit Ramachandran", "http://prajitr.github.io/"] + - ["Mathias Bynens", "http://mathiasbynens.be/"] +translators: + - ["Suzane Sant Ana", "http://github.com/suuuzi"] + - ["Rodrigo Muniz", "http://github.com/muniz95"] +lang: pt-br +--- + +Brainfuck (em letras minúsculas, exceto no início de frases) é uma linguagem de +programação Turing-completa extremamente simples com apenas 8 comandos. + +``` +Qualquer caractere exceto "><+-.,[]" (sem contar as aspas) é ignorado. + +Brainfuck é representado por um vetor com 30 000 células inicializadas em zero +e um ponteiro de dados que aponta para a célula atual. + +Existem 8 comandos: ++ : Incrementa o valor da célula atual em 1. +- : Decrementa o valor da célula atual em 1. +> : Move o ponteiro de dados para a célula seguinte (célula à direita). +< : Move o ponteiro de dados para a célula anterior (célula à esquerda). +. : Imprime o valor ASCII da célula atual. (ex. 65 = 'A'). +, : Lê um único caractere para a célula atual. +[ : Se o valor da célula atual for zero, salta para o ] correspondente. + Caso contrário, passa para a instrução seguinte. +] : Se o valor da célula atual for zero, passa para a instrução seguinte. + Caso contrário, volta para a instrução relativa ao [ correspondente. + +[ e ] formam um ciclo while. Obviamente, devem ser equilibrados. + +Vamos ver alguns exemplos básicos em brainfuck: + +++++++ [ > ++++++++++ < - ] > +++++ . + +Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6. +A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se +o ponteiro de dados para a célula #2. O valor da célula #2 é incrementado 10 +vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se +a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para +a célula #1 chegar a 0, momento em que se salta para o ] correspondente, +continuando com a instrução seguinte). + +Nesta altura estamos na célula #1, cujo valor é 0, enquanto a célula #2 +tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5 +vezes para um valor final de 65, e então é impresso o valor da célula #2. O valor +65 corresponde ao caractere 'A' em ASCII, então 'A' é impresso no terminal. + +, [ > + < - ] > . + +Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é +iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na +célula #2, movemos o ponteiro de dados de volta para a célula #1 e finalmente +decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser +igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de +dados está apontando para a célula #1 no fim do ciclo, movemos o ponteiro para a +célula #2 e imprimimos o valor em ASCII. + +Os espaços servem apenas para tornar o programa mais legível. Podemos escrever +o mesmo programa da seguinte maneira: + +,[>+<-]>. + +Tente descobrir o que este programa faz: + +,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> + +Este programa lê dois números e os multiplica. + +Basicamente o programa pede dois caracteres ao usuário. Depois é iniciado um +ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados +para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula +#2, incrementando o valor da célula #3. Porém existe um problema, no final do +ciclo interior: a célula #2 tem o valor 0. Para resolver este problema o valor da +célula #4 é também incrementado e copiado para a célula #2. +``` + +E isto é brainfuck. Simples, não? Por divertimento você pode escrever os +seus próprios programas em brainfuck, ou então escrever um interpretador de +brainfuck em outra linguagem. O interpretador é relativamente fácil de se +implementar, mas caso você seja masoquista, tente escrever um interpretador de +brainfuck… em brainfuck. diff --git a/pt-br/bf.html.markdown b/pt-br/bf.html.markdown deleted file mode 100644 index 52a5269e..00000000 --- a/pt-br/bf.html.markdown +++ /dev/null @@ -1,86 +0,0 @@ ---- -language: bf -filename: learnbf-pt.bf -contributors: - - ["Prajit Ramachandran", "http://prajitr.github.io/"] - - ["Mathias Bynens", "http://mathiasbynens.be/"] -translators: - - ["Suzane Sant Ana", "http://github.com/suuuzi"] - - ["Rodrigo Muniz", "http://github.com/muniz95"] -lang: pt-br ---- - -Brainfuck (em letras minúsculas, exceto no início de frases) é uma linguagem de -programação Turing-completa extremamente simples com apenas 8 comandos. - -``` -Qualquer caractere exceto "><+-.,[]" (sem contar as aspas) é ignorado. - -Brainfuck é representado por um vetor com 30 000 células inicializadas em zero -e um ponteiro de dados que aponta para a célula atual. - -Existem 8 comandos: -+ : Incrementa o valor da célula atual em 1. -- : Decrementa o valor da célula atual em 1. -> : Move o ponteiro de dados para a célula seguinte (célula à direita). -< : Move o ponteiro de dados para a célula anterior (célula à esquerda). -. : Imprime o valor ASCII da célula atual. (ex. 65 = 'A'). -, : Lê um único caractere para a célula atual. -[ : Se o valor da célula atual for zero, salta para o ] correspondente. - Caso contrário, passa para a instrução seguinte. -] : Se o valor da célula atual for zero, passa para a instrução seguinte. - Caso contrário, volta para a instrução relativa ao [ correspondente. - -[ e ] formam um ciclo while. Obviamente, devem ser equilibrados. - -Vamos ver alguns exemplos básicos em brainfuck: - -++++++ [ > ++++++++++ < - ] > +++++ . - -Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6. -A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se -o ponteiro de dados para a célula #2. O valor da célula #2 é incrementado 10 -vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se -a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para -a célula #1 chegar a 0, momento em que se salta para o ] correspondente, -continuando com a instrução seguinte). - -Nesta altura estamos na célula #1, cujo valor é 0, enquanto a célula #2 -tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5 -vezes para um valor final de 65, e então é impresso o valor da célula #2. O valor -65 corresponde ao caractere 'A' em ASCII, então 'A' é impresso no terminal. - -, [ > + < - ] > . - -Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é -iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na -célula #2, movemos o ponteiro de dados de volta para a célula #1 e finalmente -decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser -igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de -dados está apontando para a célula #1 no fim do ciclo, movemos o ponteiro para a -célula #2 e imprimimos o valor em ASCII. - -Os espaços servem apenas para tornar o programa mais legível. Podemos escrever -o mesmo programa da seguinte maneira: - -,[>+<-]>. - -Tente descobrir o que este programa faz: - -,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> - -Este programa lê dois números e os multiplica. - -Basicamente o programa pede dois caracteres ao usuário. Depois é iniciado um -ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados -para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula -#2, incrementando o valor da célula #3. Porém existe um problema, no final do -ciclo interior: a célula #2 tem o valor 0. Para resolver este problema o valor da -célula #4 é também incrementado e copiado para a célula #2. -``` - -E isto é brainfuck. Simples, não? Por divertimento você pode escrever os -seus próprios programas em brainfuck, ou então escrever um interpretador de -brainfuck em outra linguagem. O interpretador é relativamente fácil de se -implementar, mas caso você seja masoquista, tente escrever um interpretador de -brainfuck… em brainfuck. diff --git a/pt-br/csharp-pt.html.markdown b/pt-br/csharp-pt.html.markdown new file mode 100644 index 00000000..547f4817 --- /dev/null +++ b/pt-br/csharp-pt.html.markdown @@ -0,0 +1,896 @@ +--- +language: c# +filename: csharp-pt.cs +contributors: + - ["Robson Alves", "http://robsonalves.net/"] +lang: pt-br +--- + +C# é uma linguagem elegante e altamente tipado orientada a objetos que permite aos desenvolvedores criarem uma variedade de aplicações seguras e robustas que são executadas no .NET Framework. + +[Read more here.](http://msdn.microsoft.com/pt-br/library/vstudio/z1zx9t92.aspx) + +```c# +// Comentário de linha única começa com // +/* +Múltipas linhas é desta forma +*/ +/// +/// Esta é uma documentação comentário XML que pode ser usado para gerar externo +/// documentação ou fornecer ajuda de contexto dentro de um IDE +/// +//public void MethodOrClassOrOtherWithParsableHelp() {} + +// Especificar qual namespace seu código irá usar +// Os namespaces a seguir são padrões do .NET Framework Class Library +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using System.IO; + +// Mas este aqui não é : +using System.Data.Entity; +// Para que consiga utiliza-lo, você precisa adicionar novas referências +// Isso pode ser feito com o gerenciador de pacotes NuGet : `Install-Package EntityFramework` + +// Namespaces são escopos definidos para organizar o códgo em "pacotes" or "módulos" +// Usando este código a partir de outra arquivo de origem: using Learning.CSharp; +namespace Learning.CSharp +{ + // Cada .cs deve conter uma classe com o mesmo nome do arquivo + // você está autorizado a contrariar isto, mas evite por sua sanidade. + public class AprenderCsharp + { + // Sintaxe Básica - Pule para as CARACTERÍSTICAS INTERESSANTES se você ja usou Java ou C++ antes. + public static void Syntax() + { + // Use Console.WriteLine para apresentar uma linha + Console.WriteLine("Hello World"); + Console.WriteLine( + "Integer: " + 10 + + " Double: " + 3.14 + + " Boolean: " + true); + + // Para apresentar sem incluir uma nova linha, use Console.Write + Console.Write("Hello "); + Console.Write("World"); + + /////////////////////////////////////////////////// + // Tpos e Variáveis + // + // Declare uma variável usando + /////////////////////////////////////////////////// + + // Sbyte - Signed 8-bit integer + // (-128 <= sbyte <= 127) + sbyte fooSbyte = 100; + + // Byte - Unsigned 8-bit integer + // (0 <= byte <= 255) + byte fooByte = 100; + + // Short - 16-bit integer + // Signed - (-32,768 <= short <= 32,767) + // Unsigned - (0 <= ushort <= 65,535) + short fooShort = 10000; + ushort fooUshort = 10000; + + // Integer - 32-bit integer + int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) + uint fooUint = 1; // (0 <= uint <= 4,294,967,295) + + // Long - 64-bit integer + long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) + // Numbers default to being int or uint depending on size. + // L is used to denote that this variable value is of type long or ulong + + // Double - Double-precision 64-bit IEEE 754 Floating Point + double fooDouble = 123.4; // Precision: 15-16 digits + + // Float - Single-precision 32-bit IEEE 754 Floating Point + float fooFloat = 234.5f; // Precision: 7 digits + // f is used to denote that this variable value is of type float + + // Decimal - a 128-bits data type, with more precision than other floating-point types, + // suited for financial and monetary calculations + decimal fooDecimal = 150.3m; + + // Boolean - true & false + bool fooBoolean = true; // or false + + // Char - A single 16-bit Unicode character + char fooChar = 'A'; + + // Strings - ao contrário dos anteriores tipos base, que são todos os tipos de valor, +            // Uma string é um tipo de referência. Ou seja, você pode configurá-lo como nulo + string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)"; + Console.WriteLine(fooString); + + // Você pode acessar todos os caracteres de string com um indexador: + char charFromString = fooString[1]; // => 'e' + // Strings são imutáveis: você não pode fazer fooString[1] = 'X'; + + // Compare strings com sua atual cultura, ignorando maiúsculas e minúsculas + string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); + + // Formatando, baseado no sprintf + string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); + + // Datas e formatações + DateTime fooDate = DateTime.Now; + Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); + + // Você pode juntar um string em mais de duas linhas com o símbolo @. Para escapar do " use "" + string bazString = @"Here's some stuff +on a new line! ""Wow!"", the masses cried"; + + // Use const ou read-only para fazer uma variável imutável + // os valores da const são calculados durante o tempo de compilação + const int HoursWorkPerWeek = 9001; + + /////////////////////////////////////////////////// + // Estrutura de Dados + /////////////////////////////////////////////////// + + // Matrizes - zero indexado + // O tamanho do array pode ser decidido ainda na declaração + // O formato para declarar uma matriz é o seguinte: + // [] = new []; + int[] intArray = new int[10]; + + // Outra forma de declarar & inicializar uma matriz + int[] y = { 9000, 1000, 1337 }; + + // Indexando uma matriz - Acessando um elemento + Console.WriteLine("intArray @ 0: " + intArray[0]); + // Matriz são alteráveis + intArray[1] = 1; + + // Listas + // Listas são usadas frequentemente tanto quanto matriz por serem mais flexiveis + // O formato de declarar uma lista é o seguinte: + // List = new List(); + List intList = new List(); + List stringList = new List(); + List z = new List { 9000, 1000, 1337 }; // inicializar + // O <> são para genéricos - Confira está interessante seção do material + + // Lista não possuem valores padrão. + // Um valor deve ser adicionado antes e depois acessado pelo indexador + intList.Add(1); + Console.WriteLine("intList @ 0: " + intList[0]); + + // Outras estruturas de dados para conferir: + // Pilha/Fila + // Dicionário (uma implementação de map de hash) + // HashSet + // Read-only Coleção + // Tuple (.Net 4+) + + /////////////////////////////////////// + // Operadores + /////////////////////////////////////// + Console.WriteLine("\n->Operators"); + + int i1 = 1, i2 = 2; // Forma curta para declarar diversas variáveis + + // Aritmética é clara + Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 + + // Modulo + Console.WriteLine("11%3 = " + (11 % 3)); // => 2 + + // Comparações de operadores + Console.WriteLine("3 == 2? " + (3 == 2)); // => falso + Console.WriteLine("3 != 2? " + (3 != 2)); // => verdadeiro + Console.WriteLine("3 > 2? " + (3 > 2)); // => verdadeiro + Console.WriteLine("3 < 2? " + (3 < 2)); // => falso + Console.WriteLine("2 <= 2? " + (2 <= 2)); // => verdadeiro + Console.WriteLine("2 >= 2? " + (2 >= 2)); // => verdadeiro + + // Operadores bit a bit (bitwise) + /* + ~ Unário bitwise complemento + << Signed left shift + >> Signed right shift + & Bitwise AND + ^ Bitwise exclusivo OR + | Bitwise inclusivo OR + */ + + // Incrementações + int i = 0; + Console.WriteLine("\n->Inc/Dec-rementation"); + Console.WriteLine(i++); //i = 1. Post-Incrementation + Console.WriteLine(++i); //i = 2. Pre-Incrementation + Console.WriteLine(i--); //i = 1. Post-Decrementation + Console.WriteLine(--i); //i = 0. Pre-Decrementation + + /////////////////////////////////////// + // Estrutura de Controle + /////////////////////////////////////// + Console.WriteLine("\n->Control Structures"); + + // Declaração if é como a linguagem C + int j = 10; + if (j == 10) + { + Console.WriteLine("I get printed"); + } + else if (j > 10) + { + Console.WriteLine("I don't"); + } + else + { + Console.WriteLine("I also don't"); + } + + // Operador Ternário + // Um simples if/else pode ser escrito da seguinte forma + // ? : + int toCompare = 17; + string isTrue = toCompare == 17 ? "True" : "False"; + + // While loop + int fooWhile = 0; + while (fooWhile < 100) + { + //Iterated 100 times, fooWhile 0->99 + fooWhile++; + } + + // Do While Loop + int fooDoWhile = 0; + do + { + // Inicia a interação 100 vezes, fooDoWhile 0->99 + if (false) + continue; // pule a intereção atual para apróxima + + fooDoWhile++; + + if (fooDoWhile == 50) + break; // Interrompe o laço inteiro + + } while (fooDoWhile < 100); + + //estrutura de loop for => for(; ; ) + for (int fooFor = 0; fooFor < 10; fooFor++) + { + //Iterado 10 vezes, fooFor 0->9 + } + + // For Each Loop + // Estrutura do foreach => foreach( in ) + // O laço foreach percorre sobre qualquer objeto que implementa IEnumerable ou IEnumerable + // Toda a coleção de tipos (Array, List, Dictionary...) no .Net framework + // implementa uma ou mais destas interfaces. + // (O ToCharArray() pode ser removido, por que uma string também implementa IEnumerable) + foreach (char character in "Hello World".ToCharArray()) + { + //Iterated over all the characters in the string + } + + // Switch Case + // Um switch funciona com os tipos de dados byte, short, char, e int. + // Isto também funcional com tipos enumeradors (discutidos em Tipos Enum), + // A classe String, and a few special classes that wrap + // tipos primitívos: Character, Byte, Short, and Integer. + int month = 3; + string monthString; + switch (month) + { + case 1: + monthString = "January"; + break; + case 2: + monthString = "February"; + break; + case 3: + monthString = "March"; + break; + // You can assign more than one case to an action + // But you can't add an action without a break before another case + // (if you want to do this, you would have to explicitly add a goto case x + case 6: + case 7: + case 8: + monthString = "Summer time!!"; + break; + default: + monthString = "Some other month"; + break; + } + + /////////////////////////////////////// + // Converting Data Types And Typecasting + /////////////////////////////////////// + + // Converting data + + // Convert String To Integer + // this will throw a FormatException on failure + int.Parse("123");//returns an integer version of "123" + + // try parse will default to type default on failure + // in this case: 0 + int tryInt; + if (int.TryParse("123", out tryInt)) // Function is boolean + Console.WriteLine(tryInt); // 123 + + // Convert Integer To String + // Convert class has a number of methods to facilitate conversions + Convert.ToString(123); + // or + tryInt.ToString(); + + // Casting + // Cast decimal 15 to a int + // and then implicitly cast to long + long x = (int) 15M; + } + + /////////////////////////////////////// + // CLASSES - see definitions at end of file + /////////////////////////////////////// + public static void Classes() + { + // See Declaration of objects at end of file + + // Use new to instantiate a class + Bicycle trek = new Bicycle(); + + // Call object methods + trek.SpeedUp(3); // You should always use setter and getter methods + trek.Cadence = 100; + + // ToString is a convention to display the value of this Object. + Console.WriteLine("trek info: " + trek.Info()); + + // Instantiate a new Penny Farthing + PennyFarthing funbike = new PennyFarthing(1, 10); + Console.WriteLine("funbike info: " + funbike.Info()); + + Console.Read(); + } // End main method + + // CONSOLE ENTRY A console application must have a main method as an entry point + public static void Main(string[] args) + { + OtherInterestingFeatures(); + } + + // + // INTERESTING FEATURES + // + + // DEFAULT METHOD SIGNATURES + + public // Visibility + static // Allows for direct call on class without object + int // Return Type, + MethodSignatures( + int maxCount, // First variable, expects an int + int count = 0, // will default the value to 0 if not passed in + int another = 3, + params string[] otherParams // captures all other parameters passed to method + ) + { + return -1; + } + + // Methods can have the same name, as long as the signature is unique + // A method that differs only in return type is not unique + public static void MethodSignatures( + ref int maxCount, // Pass by reference + out int count) + { + count = 15; // out param must be assigned before control leaves the method + } + + // GENERICS + // The classes for TKey and TValue is specified by the user calling this function. + // This method emulates the SetDefault of Python + public static TValue SetDefault( + IDictionary dictionary, + TKey key, + TValue defaultItem) + { + TValue result; + if (!dictionary.TryGetValue(key, out result)) + return dictionary[key] = defaultItem; + return result; + } + + // You can narrow down the objects that are passed in + public static void IterateAndPrint(T toPrint) where T: IEnumerable + { + // We can iterate, since T is a IEnumerable + foreach (var item in toPrint) + // Item is an int + Console.WriteLine(item.ToString()); + } + + public static void OtherInterestingFeatures() + { + // OPTIONAL PARAMETERS + MethodSignatures(3, 1, 3, "Some", "Extra", "Strings"); + MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones + + // BY REF AND OUT PARAMETERS + int maxCount = 0, count; // ref params must have value + MethodSignatures(ref maxCount, out count); + + // EXTENSION METHODS + int i = 3; + i.Print(); // Defined below + + // NULLABLE TYPES - great for database interaction / return values + // any value type (i.e. not a class) can be made nullable by suffixing a ? + // ? = + int? nullable = null; // short hand for Nullable + Console.WriteLine("Nullable variable: " + nullable); + bool hasValue = nullable.HasValue; // true if not null + + // ?? is syntactic sugar for specifying default value (coalesce) + // in case variable is null + int notNullable = nullable ?? 0; // 0 + + // IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is: + var magic = "magic is a string, at compile time, so you still get type safety"; + // magic = 9; will not work as magic is a string, not an int + + // GENERICS + // + var phonebook = new Dictionary() { + {"Sarah", "212 555 5555"} // Add some entries to the phone book + }; + + // Calling SETDEFAULT defined as a generic above + Console.WriteLine(SetDefault(phonebook, "Shaun", "No Phone")); // No Phone + // nb, you don't need to specify the TKey and TValue since they can be + // derived implicitly + Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555 + + // LAMBDA EXPRESSIONS - allow you to write code in line + Func square = (x) => x * x; // Last T item is the return value + Console.WriteLine(square(3)); // 9 + + // ERROR HANDLING - coping with an uncertain world + try + { + var funBike = PennyFarthing.CreateWithGears(6); + + // will no longer execute because CreateWithGears throws an exception + string some = ""; + if (true) some = null; + some.ToLower(); // throws a NullReferenceException + } + catch (NotSupportedException) + { + Console.WriteLine("Not so much fun now!"); + } + catch (Exception ex) // catch all other exceptions + { + throw new ApplicationException("It hit the fan", ex); + // throw; // A rethrow that preserves the callstack + } + // catch { } // catch-all without capturing the Exception + finally + { + // executes after try or catch + } + + // DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily. + // Most of objects that access unmanaged resources (file handle, device contexts, etc.) + // implement the IDisposable interface. The using statement takes care of + // cleaning those IDisposable objects for you. + using (StreamWriter writer = new StreamWriter("log.txt")) + { + writer.WriteLine("Nothing suspicious here"); + // At the end of scope, resources will be released. + // Even if an exception is thrown. + } + + // PARALLEL FRAMEWORK + // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx + var websites = new string[] { + "http://www.google.com", "http://www.reddit.com", + "http://www.shaunmccarthy.com" + }; + var responses = new Dictionary(); + + // Will spin up separate threads for each request, and join on them + // before going to the next step! + Parallel.ForEach(websites, + new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads + website => + { + // Do something that takes a long time on the file + using (var r = WebRequest.Create(new Uri(website)).GetResponse()) + { + responses[website] = r.ContentType; + } + }); + + // This won't happen till after all requests have been completed + foreach (var key in responses.Keys) + Console.WriteLine("{0}:{1}", key, responses[key]); + + // DYNAMIC OBJECTS (great for working with other languages) + dynamic student = new ExpandoObject(); + student.FirstName = "First Name"; // No need to define class first! + + // You can even add methods (returns a string, and takes in a string) + student.Introduce = new Func( + (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo)); + Console.WriteLine(student.Introduce("Beth")); + + // IQUERYABLE - almost all collections implement this, which gives you a lot of + // very useful Map / Filter / Reduce style methods + var bikes = new List(); + bikes.Sort(); // Sorts the array + bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels + var result = bikes + .Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type) + .Where(b => b.IsBroken && b.HasTassles) + .Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable + + var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection + + // Create a list of IMPLICIT objects based on some parameters of the bike + var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); + // Hard to show here, but you get type ahead completion since the compiler can implicitly work + // out the types above! + foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) + Console.WriteLine(bikeSummary.Name); + + // ASPARALLEL + // And this is where things get wicked - combines linq and parallel operations + var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); + // this will happen in parallel! Threads will automagically be spun up and the + // results divvied amongst them! Amazing for large datasets when you have lots of + // cores + + // LINQ - maps a store to IQueryable objects, with delayed execution + // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document + var db = new BikeRepository(); + + // execution is delayed, which is great when querying a database + var filter = db.Bikes.Where(b => b.HasTassles); // no query run + if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality + filter = filter.Where(b => b.IsBroken); // no query run + + var query = filter + .OrderBy(b => b.Wheels) + .ThenBy(b => b.Name) + .Select(b => b.Name); // still no query run + + // Now the query runs, but opens a reader, so only populates are you iterate through + foreach (string bike in query) + Console.WriteLine(result); + + + + } + + } // End LearnCSharp class + + // You can include other classes in a .cs file + + public static class Extensions + { + // EXTENSION FUNCTIONS + public static void Print(this object obj) + { + Console.WriteLine(obj.ToString()); + } + } + + // Class Declaration Syntax: + // class { + // //data fields, constructors, functions all inside. + // //functions are called as methods in Java. + // } + + public class Bicycle + { + // Bicycle's Fields/Variables + public int Cadence // Public: Can be accessed from anywhere + { + get // get - define a method to retrieve the property + { + return _cadence; + } + set // set - define a method to set a proprety + { + _cadence = value; // Value is the value passed in to the setter + } + } + private int _cadence; + + protected virtual int Gear // Protected: Accessible from the class and subclasses + { + get; // creates an auto property so you don't need a member field + set; + } + + internal int Wheels // Internal: Accessible from within the assembly + { + get; + private set; // You can set modifiers on the get/set methods + } + + int _speed; // Everything is private by default: Only accessible from within this class. + // can also use keyword private + public string Name { get; set; } + + // Enum is a value type that consists of a set of named constants + // It is really just mapping a name to a value (an int, unless specified otherwise). + // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. + // An enum can't contain the same value twice. + public enum BikeBrand + { + AIST, + BMC, + Electra = 42, //you can explicitly set a value to a name + Gitane // 43 + } + // We defined this type inside a Bicycle class, so it is a nested type + // Code outside of this class should reference this type as Bicycle.Brand + + public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type + + // Decorate an enum with the FlagsAttribute to indicate that multiple values can be switched on + [Flags] // Any class derived from Attribute can be used to decorate types, methods, parameters etc + public enum BikeAccessories + { + None = 0, + Bell = 1, + MudGuards = 2, // need to set the values manually! + Racks = 4, + Lights = 8, + FullPackage = Bell | MudGuards | Racks | Lights + } + + // Usage: aBike.Accessories.HasFlag(Bicycle.BikeAccessories.Bell) + // Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell + public BikeAccessories Accessories { get; set; } + + // Static members belong to the type itself rather then specific object. + // You can access them without a reference to any object: + // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); + public static int BicyclesCreated { get; set; } + + // readonly values are set at run time + // they can only be assigned upon declaration or in a constructor + readonly bool _hasCardsInSpokes = false; // read-only private + + // Constructors are a way of creating classes + // This is a default constructor + public Bicycle() + { + this.Gear = 1; // you can access members of the object with the keyword this + Cadence = 50; // but you don't always need it + _speed = 5; + Name = "Bontrager"; + Brand = BikeBrand.AIST; + BicyclesCreated++; + } + + // This is a specified constructor (it contains arguments) + public Bicycle(int startCadence, int startSpeed, int startGear, + string name, bool hasCardsInSpokes, BikeBrand brand) + : base() // calls base first + { + Gear = startGear; + Cadence = startCadence; + _speed = startSpeed; + Name = name; + _hasCardsInSpokes = hasCardsInSpokes; + Brand = brand; + } + + // Constructors can be chained + public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : + this(startCadence, startSpeed, 0, "big wheels", true, brand) + { + } + + // Function Syntax: + // () + + // classes can implement getters and setters for their fields + // or they can implement properties (this is the preferred way in C#) + + // Method parameters can have default values. + // In this case, methods can be called with these parameters omitted + public void SpeedUp(int increment = 1) + { + _speed += increment; + } + + public void SlowDown(int decrement = 1) + { + _speed -= decrement; + } + + // properties get/set values + // when only data needs to be accessed, consider using properties. + // properties may have either get or set, or both + private bool _hasTassles; // private variable + public bool HasTassles // public accessor + { + get { return _hasTassles; } + set { _hasTassles = value; } + } + + // You can also define an automatic property in one line + // this syntax will create a backing field automatically. + // You can set an access modifier on either the getter or the setter (or both) + // to restrict its access: + public bool IsBroken { get; private set; } + + // Properties can be auto-implemented + public int FrameSize + { + get; + // you are able to specify access modifiers for either get or set + // this means only Bicycle class can call set on Framesize + private set; + } + + // It's also possible to define custom Indexers on objects. + // All though this is not entirely useful in this example, you + // could do bicycle[0] which yields "chris" to get the first passenger or + // bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle) + private string[] passengers = { "chris", "phil", "darren", "regina" }; + + public string this[int i] + { + get { + return passengers[i]; + } + + set { + return passengers[i] = value; + } + } + + //Method to display the attribute values of this Object. + public virtual string Info() + { + return "Gear: " + Gear + + " Cadence: " + Cadence + + " Speed: " + _speed + + " Name: " + Name + + " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") + + "\n------------------------------\n" + ; + } + + // Methods can also be static. It can be useful for helper methods + public static bool DidWeCreateEnoughBycles() + { + // Within a static method, we only can reference static class members + return BicyclesCreated > 9000; + } // If your class only needs static members, consider marking the class itself as static. + + + } // end class Bicycle + + // PennyFarthing is a subclass of Bicycle + class PennyFarthing : Bicycle + { + // (Penny Farthings are those bicycles with the big front wheel. + // They have no gears.) + + // calling parent constructor + public PennyFarthing(int startCadence, int startSpeed) : + base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra) + { + } + + protected override int Gear + { + get + { + return 0; + } + set + { + throw new InvalidOperationException("You can't change gears on a PennyFarthing"); + } + } + + public static PennyFarthing CreateWithGears(int gears) + { + var penny = new PennyFarthing(1, 1); + penny.Gear = gears; // Oops, can't do this! + return penny; + } + + public override string Info() + { + string result = "PennyFarthing bicycle "; + result += base.ToString(); // Calling the base version of the method + return result; + } + } + + // Interfaces only contain signatures of the members, without the implementation. + interface IJumpable + { + void Jump(int meters); // all interface members are implicitly public + } + + interface IBreakable + { + bool Broken { get; } // interfaces can contain properties as well as methods & events + } + + // Class can inherit only one other class, but can implement any amount of interfaces + class MountainBike : Bicycle, IJumpable, IBreakable + { + int damage = 0; + + public void Jump(int meters) + { + damage += meters; + } + + public bool Broken + { + get + { + return damage > 100; + } + } + } + + /// + /// Used to connect to DB for LinqToSql example. + /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional) + /// http://msdn.microsoft.com/en-us/data/jj193542.aspx + /// + public class BikeRepository : DbContext + { + public BikeRepository() + : base() + { + } + + public DbSet Bikes { get; set; } + } +} // End Namespace +``` + +## Topics Not Covered + + * Attributes + * async/await, yield, pragma directives + * Web Development + * ASP.NET MVC & WebApi (new) + * ASP.NET Web Forms (old) + * WebMatrix (tool) + * Desktop Development + * Windows Presentation Foundation (WPF) (new) + * Winforms (old) + +## Further Reading + + * [DotNetPerls](http://www.dotnetperls.com) + * [C# in Depth](http://manning.com/skeet2) + * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) + * [LINQ](http://shop.oreilly.com/product/9780596519254.do) + * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) + * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) + * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) + * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) + * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) + * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx) diff --git a/pt-br/csharp.html.markdown b/pt-br/csharp.html.markdown deleted file mode 100644 index 547f4817..00000000 --- a/pt-br/csharp.html.markdown +++ /dev/null @@ -1,896 +0,0 @@ ---- -language: c# -filename: csharp-pt.cs -contributors: - - ["Robson Alves", "http://robsonalves.net/"] -lang: pt-br ---- - -C# é uma linguagem elegante e altamente tipado orientada a objetos que permite aos desenvolvedores criarem uma variedade de aplicações seguras e robustas que são executadas no .NET Framework. - -[Read more here.](http://msdn.microsoft.com/pt-br/library/vstudio/z1zx9t92.aspx) - -```c# -// Comentário de linha única começa com // -/* -Múltipas linhas é desta forma -*/ -/// -/// Esta é uma documentação comentário XML que pode ser usado para gerar externo -/// documentação ou fornecer ajuda de contexto dentro de um IDE -/// -//public void MethodOrClassOrOtherWithParsableHelp() {} - -// Especificar qual namespace seu código irá usar -// Os namespaces a seguir são padrões do .NET Framework Class Library -using System; -using System.Collections.Generic; -using System.Dynamic; -using System.Linq; -using System.Net; -using System.Threading.Tasks; -using System.IO; - -// Mas este aqui não é : -using System.Data.Entity; -// Para que consiga utiliza-lo, você precisa adicionar novas referências -// Isso pode ser feito com o gerenciador de pacotes NuGet : `Install-Package EntityFramework` - -// Namespaces são escopos definidos para organizar o códgo em "pacotes" or "módulos" -// Usando este código a partir de outra arquivo de origem: using Learning.CSharp; -namespace Learning.CSharp -{ - // Cada .cs deve conter uma classe com o mesmo nome do arquivo - // você está autorizado a contrariar isto, mas evite por sua sanidade. - public class AprenderCsharp - { - // Sintaxe Básica - Pule para as CARACTERÍSTICAS INTERESSANTES se você ja usou Java ou C++ antes. - public static void Syntax() - { - // Use Console.WriteLine para apresentar uma linha - Console.WriteLine("Hello World"); - Console.WriteLine( - "Integer: " + 10 + - " Double: " + 3.14 + - " Boolean: " + true); - - // Para apresentar sem incluir uma nova linha, use Console.Write - Console.Write("Hello "); - Console.Write("World"); - - /////////////////////////////////////////////////// - // Tpos e Variáveis - // - // Declare uma variável usando - /////////////////////////////////////////////////// - - // Sbyte - Signed 8-bit integer - // (-128 <= sbyte <= 127) - sbyte fooSbyte = 100; - - // Byte - Unsigned 8-bit integer - // (0 <= byte <= 255) - byte fooByte = 100; - - // Short - 16-bit integer - // Signed - (-32,768 <= short <= 32,767) - // Unsigned - (0 <= ushort <= 65,535) - short fooShort = 10000; - ushort fooUshort = 10000; - - // Integer - 32-bit integer - int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) - uint fooUint = 1; // (0 <= uint <= 4,294,967,295) - - // Long - 64-bit integer - long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) - ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) - // Numbers default to being int or uint depending on size. - // L is used to denote that this variable value is of type long or ulong - - // Double - Double-precision 64-bit IEEE 754 Floating Point - double fooDouble = 123.4; // Precision: 15-16 digits - - // Float - Single-precision 32-bit IEEE 754 Floating Point - float fooFloat = 234.5f; // Precision: 7 digits - // f is used to denote that this variable value is of type float - - // Decimal - a 128-bits data type, with more precision than other floating-point types, - // suited for financial and monetary calculations - decimal fooDecimal = 150.3m; - - // Boolean - true & false - bool fooBoolean = true; // or false - - // Char - A single 16-bit Unicode character - char fooChar = 'A'; - - // Strings - ao contrário dos anteriores tipos base, que são todos os tipos de valor, -            // Uma string é um tipo de referência. Ou seja, você pode configurá-lo como nulo - string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)"; - Console.WriteLine(fooString); - - // Você pode acessar todos os caracteres de string com um indexador: - char charFromString = fooString[1]; // => 'e' - // Strings são imutáveis: você não pode fazer fooString[1] = 'X'; - - // Compare strings com sua atual cultura, ignorando maiúsculas e minúsculas - string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); - - // Formatando, baseado no sprintf - string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); - - // Datas e formatações - DateTime fooDate = DateTime.Now; - Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); - - // Você pode juntar um string em mais de duas linhas com o símbolo @. Para escapar do " use "" - string bazString = @"Here's some stuff -on a new line! ""Wow!"", the masses cried"; - - // Use const ou read-only para fazer uma variável imutável - // os valores da const são calculados durante o tempo de compilação - const int HoursWorkPerWeek = 9001; - - /////////////////////////////////////////////////// - // Estrutura de Dados - /////////////////////////////////////////////////// - - // Matrizes - zero indexado - // O tamanho do array pode ser decidido ainda na declaração - // O formato para declarar uma matriz é o seguinte: - // [] = new []; - int[] intArray = new int[10]; - - // Outra forma de declarar & inicializar uma matriz - int[] y = { 9000, 1000, 1337 }; - - // Indexando uma matriz - Acessando um elemento - Console.WriteLine("intArray @ 0: " + intArray[0]); - // Matriz são alteráveis - intArray[1] = 1; - - // Listas - // Listas são usadas frequentemente tanto quanto matriz por serem mais flexiveis - // O formato de declarar uma lista é o seguinte: - // List = new List(); - List intList = new List(); - List stringList = new List(); - List z = new List { 9000, 1000, 1337 }; // inicializar - // O <> são para genéricos - Confira está interessante seção do material - - // Lista não possuem valores padrão. - // Um valor deve ser adicionado antes e depois acessado pelo indexador - intList.Add(1); - Console.WriteLine("intList @ 0: " + intList[0]); - - // Outras estruturas de dados para conferir: - // Pilha/Fila - // Dicionário (uma implementação de map de hash) - // HashSet - // Read-only Coleção - // Tuple (.Net 4+) - - /////////////////////////////////////// - // Operadores - /////////////////////////////////////// - Console.WriteLine("\n->Operators"); - - int i1 = 1, i2 = 2; // Forma curta para declarar diversas variáveis - - // Aritmética é clara - Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 - - // Modulo - Console.WriteLine("11%3 = " + (11 % 3)); // => 2 - - // Comparações de operadores - Console.WriteLine("3 == 2? " + (3 == 2)); // => falso - Console.WriteLine("3 != 2? " + (3 != 2)); // => verdadeiro - Console.WriteLine("3 > 2? " + (3 > 2)); // => verdadeiro - Console.WriteLine("3 < 2? " + (3 < 2)); // => falso - Console.WriteLine("2 <= 2? " + (2 <= 2)); // => verdadeiro - Console.WriteLine("2 >= 2? " + (2 >= 2)); // => verdadeiro - - // Operadores bit a bit (bitwise) - /* - ~ Unário bitwise complemento - << Signed left shift - >> Signed right shift - & Bitwise AND - ^ Bitwise exclusivo OR - | Bitwise inclusivo OR - */ - - // Incrementações - int i = 0; - Console.WriteLine("\n->Inc/Dec-rementation"); - Console.WriteLine(i++); //i = 1. Post-Incrementation - Console.WriteLine(++i); //i = 2. Pre-Incrementation - Console.WriteLine(i--); //i = 1. Post-Decrementation - Console.WriteLine(--i); //i = 0. Pre-Decrementation - - /////////////////////////////////////// - // Estrutura de Controle - /////////////////////////////////////// - Console.WriteLine("\n->Control Structures"); - - // Declaração if é como a linguagem C - int j = 10; - if (j == 10) - { - Console.WriteLine("I get printed"); - } - else if (j > 10) - { - Console.WriteLine("I don't"); - } - else - { - Console.WriteLine("I also don't"); - } - - // Operador Ternário - // Um simples if/else pode ser escrito da seguinte forma - // ? : - int toCompare = 17; - string isTrue = toCompare == 17 ? "True" : "False"; - - // While loop - int fooWhile = 0; - while (fooWhile < 100) - { - //Iterated 100 times, fooWhile 0->99 - fooWhile++; - } - - // Do While Loop - int fooDoWhile = 0; - do - { - // Inicia a interação 100 vezes, fooDoWhile 0->99 - if (false) - continue; // pule a intereção atual para apróxima - - fooDoWhile++; - - if (fooDoWhile == 50) - break; // Interrompe o laço inteiro - - } while (fooDoWhile < 100); - - //estrutura de loop for => for(; ; ) - for (int fooFor = 0; fooFor < 10; fooFor++) - { - //Iterado 10 vezes, fooFor 0->9 - } - - // For Each Loop - // Estrutura do foreach => foreach( in ) - // O laço foreach percorre sobre qualquer objeto que implementa IEnumerable ou IEnumerable - // Toda a coleção de tipos (Array, List, Dictionary...) no .Net framework - // implementa uma ou mais destas interfaces. - // (O ToCharArray() pode ser removido, por que uma string também implementa IEnumerable) - foreach (char character in "Hello World".ToCharArray()) - { - //Iterated over all the characters in the string - } - - // Switch Case - // Um switch funciona com os tipos de dados byte, short, char, e int. - // Isto também funcional com tipos enumeradors (discutidos em Tipos Enum), - // A classe String, and a few special classes that wrap - // tipos primitívos: Character, Byte, Short, and Integer. - int month = 3; - string monthString; - switch (month) - { - case 1: - monthString = "January"; - break; - case 2: - monthString = "February"; - break; - case 3: - monthString = "March"; - break; - // You can assign more than one case to an action - // But you can't add an action without a break before another case - // (if you want to do this, you would have to explicitly add a goto case x - case 6: - case 7: - case 8: - monthString = "Summer time!!"; - break; - default: - monthString = "Some other month"; - break; - } - - /////////////////////////////////////// - // Converting Data Types And Typecasting - /////////////////////////////////////// - - // Converting data - - // Convert String To Integer - // this will throw a FormatException on failure - int.Parse("123");//returns an integer version of "123" - - // try parse will default to type default on failure - // in this case: 0 - int tryInt; - if (int.TryParse("123", out tryInt)) // Function is boolean - Console.WriteLine(tryInt); // 123 - - // Convert Integer To String - // Convert class has a number of methods to facilitate conversions - Convert.ToString(123); - // or - tryInt.ToString(); - - // Casting - // Cast decimal 15 to a int - // and then implicitly cast to long - long x = (int) 15M; - } - - /////////////////////////////////////// - // CLASSES - see definitions at end of file - /////////////////////////////////////// - public static void Classes() - { - // See Declaration of objects at end of file - - // Use new to instantiate a class - Bicycle trek = new Bicycle(); - - // Call object methods - trek.SpeedUp(3); // You should always use setter and getter methods - trek.Cadence = 100; - - // ToString is a convention to display the value of this Object. - Console.WriteLine("trek info: " + trek.Info()); - - // Instantiate a new Penny Farthing - PennyFarthing funbike = new PennyFarthing(1, 10); - Console.WriteLine("funbike info: " + funbike.Info()); - - Console.Read(); - } // End main method - - // CONSOLE ENTRY A console application must have a main method as an entry point - public static void Main(string[] args) - { - OtherInterestingFeatures(); - } - - // - // INTERESTING FEATURES - // - - // DEFAULT METHOD SIGNATURES - - public // Visibility - static // Allows for direct call on class without object - int // Return Type, - MethodSignatures( - int maxCount, // First variable, expects an int - int count = 0, // will default the value to 0 if not passed in - int another = 3, - params string[] otherParams // captures all other parameters passed to method - ) - { - return -1; - } - - // Methods can have the same name, as long as the signature is unique - // A method that differs only in return type is not unique - public static void MethodSignatures( - ref int maxCount, // Pass by reference - out int count) - { - count = 15; // out param must be assigned before control leaves the method - } - - // GENERICS - // The classes for TKey and TValue is specified by the user calling this function. - // This method emulates the SetDefault of Python - public static TValue SetDefault( - IDictionary dictionary, - TKey key, - TValue defaultItem) - { - TValue result; - if (!dictionary.TryGetValue(key, out result)) - return dictionary[key] = defaultItem; - return result; - } - - // You can narrow down the objects that are passed in - public static void IterateAndPrint(T toPrint) where T: IEnumerable - { - // We can iterate, since T is a IEnumerable - foreach (var item in toPrint) - // Item is an int - Console.WriteLine(item.ToString()); - } - - public static void OtherInterestingFeatures() - { - // OPTIONAL PARAMETERS - MethodSignatures(3, 1, 3, "Some", "Extra", "Strings"); - MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones - - // BY REF AND OUT PARAMETERS - int maxCount = 0, count; // ref params must have value - MethodSignatures(ref maxCount, out count); - - // EXTENSION METHODS - int i = 3; - i.Print(); // Defined below - - // NULLABLE TYPES - great for database interaction / return values - // any value type (i.e. not a class) can be made nullable by suffixing a ? - // ? = - int? nullable = null; // short hand for Nullable - Console.WriteLine("Nullable variable: " + nullable); - bool hasValue = nullable.HasValue; // true if not null - - // ?? is syntactic sugar for specifying default value (coalesce) - // in case variable is null - int notNullable = nullable ?? 0; // 0 - - // IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is: - var magic = "magic is a string, at compile time, so you still get type safety"; - // magic = 9; will not work as magic is a string, not an int - - // GENERICS - // - var phonebook = new Dictionary() { - {"Sarah", "212 555 5555"} // Add some entries to the phone book - }; - - // Calling SETDEFAULT defined as a generic above - Console.WriteLine(SetDefault(phonebook, "Shaun", "No Phone")); // No Phone - // nb, you don't need to specify the TKey and TValue since they can be - // derived implicitly - Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555 - - // LAMBDA EXPRESSIONS - allow you to write code in line - Func square = (x) => x * x; // Last T item is the return value - Console.WriteLine(square(3)); // 9 - - // ERROR HANDLING - coping with an uncertain world - try - { - var funBike = PennyFarthing.CreateWithGears(6); - - // will no longer execute because CreateWithGears throws an exception - string some = ""; - if (true) some = null; - some.ToLower(); // throws a NullReferenceException - } - catch (NotSupportedException) - { - Console.WriteLine("Not so much fun now!"); - } - catch (Exception ex) // catch all other exceptions - { - throw new ApplicationException("It hit the fan", ex); - // throw; // A rethrow that preserves the callstack - } - // catch { } // catch-all without capturing the Exception - finally - { - // executes after try or catch - } - - // DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily. - // Most of objects that access unmanaged resources (file handle, device contexts, etc.) - // implement the IDisposable interface. The using statement takes care of - // cleaning those IDisposable objects for you. - using (StreamWriter writer = new StreamWriter("log.txt")) - { - writer.WriteLine("Nothing suspicious here"); - // At the end of scope, resources will be released. - // Even if an exception is thrown. - } - - // PARALLEL FRAMEWORK - // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx - var websites = new string[] { - "http://www.google.com", "http://www.reddit.com", - "http://www.shaunmccarthy.com" - }; - var responses = new Dictionary(); - - // Will spin up separate threads for each request, and join on them - // before going to the next step! - Parallel.ForEach(websites, - new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads - website => - { - // Do something that takes a long time on the file - using (var r = WebRequest.Create(new Uri(website)).GetResponse()) - { - responses[website] = r.ContentType; - } - }); - - // This won't happen till after all requests have been completed - foreach (var key in responses.Keys) - Console.WriteLine("{0}:{1}", key, responses[key]); - - // DYNAMIC OBJECTS (great for working with other languages) - dynamic student = new ExpandoObject(); - student.FirstName = "First Name"; // No need to define class first! - - // You can even add methods (returns a string, and takes in a string) - student.Introduce = new Func( - (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo)); - Console.WriteLine(student.Introduce("Beth")); - - // IQUERYABLE - almost all collections implement this, which gives you a lot of - // very useful Map / Filter / Reduce style methods - var bikes = new List(); - bikes.Sort(); // Sorts the array - bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels - var result = bikes - .Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type) - .Where(b => b.IsBroken && b.HasTassles) - .Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable - - var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection - - // Create a list of IMPLICIT objects based on some parameters of the bike - var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); - // Hard to show here, but you get type ahead completion since the compiler can implicitly work - // out the types above! - foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) - Console.WriteLine(bikeSummary.Name); - - // ASPARALLEL - // And this is where things get wicked - combines linq and parallel operations - var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); - // this will happen in parallel! Threads will automagically be spun up and the - // results divvied amongst them! Amazing for large datasets when you have lots of - // cores - - // LINQ - maps a store to IQueryable objects, with delayed execution - // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document - var db = new BikeRepository(); - - // execution is delayed, which is great when querying a database - var filter = db.Bikes.Where(b => b.HasTassles); // no query run - if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality - filter = filter.Where(b => b.IsBroken); // no query run - - var query = filter - .OrderBy(b => b.Wheels) - .ThenBy(b => b.Name) - .Select(b => b.Name); // still no query run - - // Now the query runs, but opens a reader, so only populates are you iterate through - foreach (string bike in query) - Console.WriteLine(result); - - - - } - - } // End LearnCSharp class - - // You can include other classes in a .cs file - - public static class Extensions - { - // EXTENSION FUNCTIONS - public static void Print(this object obj) - { - Console.WriteLine(obj.ToString()); - } - } - - // Class Declaration Syntax: - // class { - // //data fields, constructors, functions all inside. - // //functions are called as methods in Java. - // } - - public class Bicycle - { - // Bicycle's Fields/Variables - public int Cadence // Public: Can be accessed from anywhere - { - get // get - define a method to retrieve the property - { - return _cadence; - } - set // set - define a method to set a proprety - { - _cadence = value; // Value is the value passed in to the setter - } - } - private int _cadence; - - protected virtual int Gear // Protected: Accessible from the class and subclasses - { - get; // creates an auto property so you don't need a member field - set; - } - - internal int Wheels // Internal: Accessible from within the assembly - { - get; - private set; // You can set modifiers on the get/set methods - } - - int _speed; // Everything is private by default: Only accessible from within this class. - // can also use keyword private - public string Name { get; set; } - - // Enum is a value type that consists of a set of named constants - // It is really just mapping a name to a value (an int, unless specified otherwise). - // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. - // An enum can't contain the same value twice. - public enum BikeBrand - { - AIST, - BMC, - Electra = 42, //you can explicitly set a value to a name - Gitane // 43 - } - // We defined this type inside a Bicycle class, so it is a nested type - // Code outside of this class should reference this type as Bicycle.Brand - - public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type - - // Decorate an enum with the FlagsAttribute to indicate that multiple values can be switched on - [Flags] // Any class derived from Attribute can be used to decorate types, methods, parameters etc - public enum BikeAccessories - { - None = 0, - Bell = 1, - MudGuards = 2, // need to set the values manually! - Racks = 4, - Lights = 8, - FullPackage = Bell | MudGuards | Racks | Lights - } - - // Usage: aBike.Accessories.HasFlag(Bicycle.BikeAccessories.Bell) - // Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell - public BikeAccessories Accessories { get; set; } - - // Static members belong to the type itself rather then specific object. - // You can access them without a reference to any object: - // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); - public static int BicyclesCreated { get; set; } - - // readonly values are set at run time - // they can only be assigned upon declaration or in a constructor - readonly bool _hasCardsInSpokes = false; // read-only private - - // Constructors are a way of creating classes - // This is a default constructor - public Bicycle() - { - this.Gear = 1; // you can access members of the object with the keyword this - Cadence = 50; // but you don't always need it - _speed = 5; - Name = "Bontrager"; - Brand = BikeBrand.AIST; - BicyclesCreated++; - } - - // This is a specified constructor (it contains arguments) - public Bicycle(int startCadence, int startSpeed, int startGear, - string name, bool hasCardsInSpokes, BikeBrand brand) - : base() // calls base first - { - Gear = startGear; - Cadence = startCadence; - _speed = startSpeed; - Name = name; - _hasCardsInSpokes = hasCardsInSpokes; - Brand = brand; - } - - // Constructors can be chained - public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : - this(startCadence, startSpeed, 0, "big wheels", true, brand) - { - } - - // Function Syntax: - // () - - // classes can implement getters and setters for their fields - // or they can implement properties (this is the preferred way in C#) - - // Method parameters can have default values. - // In this case, methods can be called with these parameters omitted - public void SpeedUp(int increment = 1) - { - _speed += increment; - } - - public void SlowDown(int decrement = 1) - { - _speed -= decrement; - } - - // properties get/set values - // when only data needs to be accessed, consider using properties. - // properties may have either get or set, or both - private bool _hasTassles; // private variable - public bool HasTassles // public accessor - { - get { return _hasTassles; } - set { _hasTassles = value; } - } - - // You can also define an automatic property in one line - // this syntax will create a backing field automatically. - // You can set an access modifier on either the getter or the setter (or both) - // to restrict its access: - public bool IsBroken { get; private set; } - - // Properties can be auto-implemented - public int FrameSize - { - get; - // you are able to specify access modifiers for either get or set - // this means only Bicycle class can call set on Framesize - private set; - } - - // It's also possible to define custom Indexers on objects. - // All though this is not entirely useful in this example, you - // could do bicycle[0] which yields "chris" to get the first passenger or - // bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle) - private string[] passengers = { "chris", "phil", "darren", "regina" }; - - public string this[int i] - { - get { - return passengers[i]; - } - - set { - return passengers[i] = value; - } - } - - //Method to display the attribute values of this Object. - public virtual string Info() - { - return "Gear: " + Gear + - " Cadence: " + Cadence + - " Speed: " + _speed + - " Name: " + Name + - " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") + - "\n------------------------------\n" - ; - } - - // Methods can also be static. It can be useful for helper methods - public static bool DidWeCreateEnoughBycles() - { - // Within a static method, we only can reference static class members - return BicyclesCreated > 9000; - } // If your class only needs static members, consider marking the class itself as static. - - - } // end class Bicycle - - // PennyFarthing is a subclass of Bicycle - class PennyFarthing : Bicycle - { - // (Penny Farthings are those bicycles with the big front wheel. - // They have no gears.) - - // calling parent constructor - public PennyFarthing(int startCadence, int startSpeed) : - base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra) - { - } - - protected override int Gear - { - get - { - return 0; - } - set - { - throw new InvalidOperationException("You can't change gears on a PennyFarthing"); - } - } - - public static PennyFarthing CreateWithGears(int gears) - { - var penny = new PennyFarthing(1, 1); - penny.Gear = gears; // Oops, can't do this! - return penny; - } - - public override string Info() - { - string result = "PennyFarthing bicycle "; - result += base.ToString(); // Calling the base version of the method - return result; - } - } - - // Interfaces only contain signatures of the members, without the implementation. - interface IJumpable - { - void Jump(int meters); // all interface members are implicitly public - } - - interface IBreakable - { - bool Broken { get; } // interfaces can contain properties as well as methods & events - } - - // Class can inherit only one other class, but can implement any amount of interfaces - class MountainBike : Bicycle, IJumpable, IBreakable - { - int damage = 0; - - public void Jump(int meters) - { - damage += meters; - } - - public bool Broken - { - get - { - return damage > 100; - } - } - } - - /// - /// Used to connect to DB for LinqToSql example. - /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional) - /// http://msdn.microsoft.com/en-us/data/jj193542.aspx - /// - public class BikeRepository : DbContext - { - public BikeRepository() - : base() - { - } - - public DbSet Bikes { get; set; } - } -} // End Namespace -``` - -## Topics Not Covered - - * Attributes - * async/await, yield, pragma directives - * Web Development - * ASP.NET MVC & WebApi (new) - * ASP.NET Web Forms (old) - * WebMatrix (tool) - * Desktop Development - * Windows Presentation Foundation (WPF) (new) - * Winforms (old) - -## Further Reading - - * [DotNetPerls](http://www.dotnetperls.com) - * [C# in Depth](http://manning.com/skeet2) - * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) - * [LINQ](http://shop.oreilly.com/product/9780596519254.do) - * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) - * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) - * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) - * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) - * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) - * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx) diff --git a/pt-br/elixir-pt.html.markdown b/pt-br/elixir-pt.html.markdown new file mode 100644 index 00000000..f8c56101 --- /dev/null +++ b/pt-br/elixir-pt.html.markdown @@ -0,0 +1,412 @@ +--- +language: elixir +contributors: + - ["Joao Marques", "http://github.com/mrshankly"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] +translators: + - ["Rodrigo Muniz", "http://github.com/muniz95"] +lang: pt-br +filename: learnelixir-pt.ex +--- + +Elixir é uma linguagem funcional moderna construída no topo da Erlang VM. +É totalmente compatível com Erlang, porém conta com uma sintaxe mais padronizada +e muitos outros recursos. + +```elixir + +# Comentários de linha única começam com um símbolo de número. + +# Não há comentários de múltiplas linhas, +# mas você pode empilhar os comentários. + +# Para usar o shell do elixir use o comando `iex`. +# Compile seus módulos com o comando `elixirc`. + +# Ambos devem estar em seu path se você instalou o Elixir corretamente. + +## --------------------------- +## -- Tipos Básicos +## --------------------------- + +# Há números +3 # integer +0x1F # integer +3.0 # float + +# Atoms, que são literais, uma constante com nome. Elas começam com `:`. +:hello # atom + +# Tuplas que são guardadas contiguamente em memória. +{1,2,3} # tupla + +# Podemos acessar um elemento de uma tupla om a função `elem`: +elem({1, 2, 3}, 0) #=> 1 + +# Listas que são implementadas como listas ligadas. +[1,2,3] # lista + +# Podemos acessar a primeira posição (head) e o resto (tail) de uma lista como a seguir: +[head | tail] = [1,2,3] +head #=> 1 +tail #=> [2,3] + +# Em elixir, bem como em Erlang, o sinal `=` denota pattern match, +# e não uma atribuição. +# +# Isto significa que o que estiver à esquerda (pattern) é comparado com o que +# estiver à direita. +# +# É assim que o exemplo acima de acesso à head e tail de uma lista funciona. + +# Um pattern match retornará erro quando os lados não conferem, como neste exemplo +# onde as tuplas tem diferentes tamanhos. +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} + +# Também há binários +<<1,2,3>> # binary + +# Strings e char lists +"hello" # string +'hello' # char list + +# Strings de múltiplas linhas +""" +Strings +de múltiplas +linhas. +""" +#=> "Strings\nde múltiplas\nlinhas" + +# Strings são sempre codificadas em UTF-8: +"héllò" #=> "héllò" + +# Strings são de fato apenas binários, e char lists apenas listas. +<> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# `?a` em elixir retorna o valor ASCII para a letra `a` +?a #=> 97 + +# Para concatenar listas use `++`, para binários use `<>` +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'hello ' ++ 'world' #=> 'hello world' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"hello " <> "world" #=> "hello world" + +# Ranges são representados como `início..fim` (ambos inclusivos) +1..10 #=> 1..10 +menor..maior = 1..10 # Pattern matching pode ser usada em ranges também +[lower, upper] #=> [1, 10] + +## --------------------------- +## -- Operadores +## --------------------------- + +# Matemática básica +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# Em elixir o operador `/` sempre retorna um float. + +# Para divisão de inteiros use `div` +div(10, 2) #=> 5 + +# Para obter o resto da divisão use `rem` +rem(10, 3) #=> 1 + +# Há também operadores booleanos: `or`, `and` e `not`. +# Estes operadores esperam um booleano como primeiro argumento. +true and true #=> true +false or true #=> true +# 1 and true #=> ** (ArgumentError) argument error + +# Elixir também fornece `||`, `&&` e `!` que aceitam argumentos de qualquer tipo. +# Todos os valores exceto `false` e `nil` serão avaliados como true. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil +!true #=> false + +# Para comparações temos: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` e `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# `===` e `!==` são mais estritos ao comparar integers e floats: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# Podemos comparar também dois tipos de dados diferentes: +1 < :hello #=> true + +# A regra de ordenação no geral é definida abaixo: +# number < atom < reference < functions < port < pid < tuple < list < bit string + +# Ao citar Joe Armstrong nisto: "A ordem de fato não é importante, +# mas que uma ordem total esteja bem definida é importante." + +## --------------------------- +## -- Fluxo de Controle +## --------------------------- + +# expressão `if` +if false do + "Isso nunca será visto" +else + "Isso será" +end + +# Também há `unless` +unless true do + "Isso nunca será visto" +else + "Isso será" +end + +# Lembra do patter matching? Muitas estruturas de fluxo de controle em elixir contam com ela. + +# `case` nos permite comparar um valor com muitos patterns: +case {:um, :dois} do + {:quatro, :cinco} -> + "Isso não corresponde" + {:um, x} -> + "Isso corresponde e vincula `x` a `:dois`" + _ -> + "Isso corresponde a qualquer valor" +end + +# É comum vincular o valor a `_` se não precisamos dele. +# Por exemplo, se apenas a head de uma lista nos interessa: +[head | _] = [1,2,3] +head #=> 1 + +# Para melhor legibilidade podemos fazer o seguinte: +[head | _tail] = [:a, :b, :c] +head #=> :a + +# `cond` nos permite verificar várias condições ao mesmo tempo. +# Use `cond` em vez de aninhar vários `if`'s. +cond do + 1 + 1 == 3 -> + "Nunca serei visto" + 2 * 5 == 12 -> + "Nem eu" + 1 + 2 == 3 -> + "Mas eu serei" +end + +# É comum definir a última condição igual a `true`, que sempre irá corresponder. +cond do + 1 + 1 == 3 -> + "Nunca serei visto" + 2 * 5 == 12 -> + "Nem eu" + true -> + "Mas eu serei (isso é essencialmente um else)" +end + +# `try/catch` é usado para capturar valores que são lançados, também suporta uma +# cláusula `after` que é invocada havendo um valor capturado ou não. +try do + throw(:hello) +catch + message -> "Deu #{mensagem}." +after + IO.puts("Sou o after.") +end +#=> Sou o after +# "Deu :hello" + +## --------------------------- +## -- Módulos e Funções +## --------------------------- + +# Funções Anônimas (repare o ponto) +square = fn(x) -> x * x end +square.(5) #=> 25 + +# Elas também aceitam várias cláusulas e guards. +# Guards permitem ajustes finos de pattern matching, +# sendo indicados pela palavra `when`: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir também fornece várias funções embutidas. +# Estas estão disponíveis no escopo atual. +is_number(10) #=> true +is_list("ola") #=> false +elem({1,2,3}, 0) #=> 1 + +# Você pode agrupar algumas funções em um módulo. Dentro de um módulo use `def` +# para definir suas funções. +defmodule Math do + def sum(a, b) do + a + b + end + + def square(x) do + x * x + end +end + +Math.sum(1, 2) #=> 3 +Math.square(3) #=> 9 + +# Para compilar o módulo Math salve-o como `math.ex` e use `elixirc` +# em seu terminal: elixirc math.ex + +# Dentro de um módulo podemos definir funções com `def` e funções privadas com `defp`. +# Uma função definida com `def` pode ser invocada por outros módulos, +# já uma função privada pode ser invocada apenas localmente. +defmodule PrivateMath do + def sum(a, b) do + do_sum(a, b) + end + + defp do_sum(a, b) do + a + b + end +end + +PrivateMath.sum(1, 2) #=> 3 +# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) + +# Declarações de funções também suportam guards cláusulas múltiplas: +defmodule Geometry do + def area({:rectangle, w, h}) do + w * h + end + + def area({:circle, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometry.area({:rectangle, 2, 3}) #=> 6 +Geometry.area({:circle, 3}) #=> 28.25999999999999801048 +# Geometry.area({:circle, "not_a_number"}) +#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 + +# Devido à imutabilidade, recursão é uma grande parte do elixir +defmodule Recursion do + def sum_list([head | tail], acc) do + sum_list(tail, acc + head) + end + + def sum_list([], acc) do + acc + end +end + +Recursion.sum_list([1,2,3], 0) #=> 6 + +# Módulos do elixir suportam atributos, hpa atributos embutidos e você +# pode também adicionar os seus próprios. +defmodule MyMod do + @moduledoc """ + Este é um atributo embutido em um módulo de exemplo. + """ + + @my_data 100 # Este é um atributo customizado. + IO.inspect(@my_data) #=> 100 +end + +## --------------------------- +## -- Structs e Exceptions +## --------------------------- + +# Structs são extensões no topo de mapas que trazem valores padrão, +# garantias em tempo de compilação e polimorfismo para o Elixir. +defmodule Pessoa do + defstruct nome: nil, idade: 0, peso: 0 +end + +joe_info = %Pessoa{ nome: "Joe", idade: 30, peso: 180 } +#=> %Pessoa{idade: 30, peso: 180, nome: "Joe"} + +# Acessa o valor de nome +joe_info.name #=> "Joe" + +# Atualiza o valor de idade +older_joe_info = %{ joe_info | idade: 31 } +#=> %Pessoa{idade: 31, peso: 180, nome: "Joe"} + +# O bloco `try` com a palavra `rescue` é usado para manipular exceções +try do + raise "algum erro" +rescue + RuntimeError -> "resgatado um erro em tempo de execução" + _error -> "isso resgatará qualquer erro" +end + +# Toda exceção possui uma mensagem +try do + raise "algum erro" +rescue + x in [RuntimeError] -> + x.message +end + +## --------------------------- +## -- Concorrência +## --------------------------- + +# Elixir conta com o modelo de ator para concorrência. Tudo o que precisamos para +# escrever programas concorrentes em elixir são três primitivos: spawning processes, +# sending messages e receiving messages. + +# Para iniciar um novo processo usamos a função `spawn`, a qual leva uma função +# como argumento. +f = fn -> 2 * 2 end #=> #Function +spawn(f) #=> #PID<0.40.0> + +# `spawn` retorna um pid (process identifier), você pode usar esse pid para enviar +# mensagens ao processo. Para envio de mensagens usamos o operador `send`. +# Para tudo isso ser útil precisamos estar aptos a receber mensagens. Isto é +# realizado com o mecanismo `receive`: +defmodule Geometry do + def area_loop do + receive do + {:rectangle, w, h} -> + IO.puts("Area = #{w * h}") + area_loop() + {:circle, r} -> + IO.puts("Area = #{3.14 * r * r}") + area_loop() + end + end +end + +# Compile o módulo e crie um processo que avalie `area_loop` no shell +pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> + +# Envia uma mensagem ao `pid` correspondente a um pattern na declaração de recebimento +send pid, {:rectangle, 2, 3} +#=> Area = 6 +# {:rectangle,2,3} + +send pid, {:circle, 2} +#=> Area = 12.56000000000000049738 +# {:circle,2} + +# O shell também é um processo, você pode usar `self` para obter o pid atual +self() #=> #PID<0.27.0> +``` + +## Referências + +* [Getting started guide](http://elixir-lang.org/getting_started/1.html) da [página do elixir](http://elixir-lang.org) +* [Elixir Documentation](http://elixir-lang.org/docs/master/) +* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) por Dave Thomas +* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) +* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) por Fred Hebert +* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) por Joe Armstrong diff --git a/pt-br/elixir.html.markdown b/pt-br/elixir.html.markdown deleted file mode 100644 index f8c56101..00000000 --- a/pt-br/elixir.html.markdown +++ /dev/null @@ -1,412 +0,0 @@ ---- -language: elixir -contributors: - - ["Joao Marques", "http://github.com/mrshankly"] - - ["Dzianis Dashkevich", "https://github.com/dskecse"] -translators: - - ["Rodrigo Muniz", "http://github.com/muniz95"] -lang: pt-br -filename: learnelixir-pt.ex ---- - -Elixir é uma linguagem funcional moderna construída no topo da Erlang VM. -É totalmente compatível com Erlang, porém conta com uma sintaxe mais padronizada -e muitos outros recursos. - -```elixir - -# Comentários de linha única começam com um símbolo de número. - -# Não há comentários de múltiplas linhas, -# mas você pode empilhar os comentários. - -# Para usar o shell do elixir use o comando `iex`. -# Compile seus módulos com o comando `elixirc`. - -# Ambos devem estar em seu path se você instalou o Elixir corretamente. - -## --------------------------- -## -- Tipos Básicos -## --------------------------- - -# Há números -3 # integer -0x1F # integer -3.0 # float - -# Atoms, que são literais, uma constante com nome. Elas começam com `:`. -:hello # atom - -# Tuplas que são guardadas contiguamente em memória. -{1,2,3} # tupla - -# Podemos acessar um elemento de uma tupla om a função `elem`: -elem({1, 2, 3}, 0) #=> 1 - -# Listas que são implementadas como listas ligadas. -[1,2,3] # lista - -# Podemos acessar a primeira posição (head) e o resto (tail) de uma lista como a seguir: -[head | tail] = [1,2,3] -head #=> 1 -tail #=> [2,3] - -# Em elixir, bem como em Erlang, o sinal `=` denota pattern match, -# e não uma atribuição. -# -# Isto significa que o que estiver à esquerda (pattern) é comparado com o que -# estiver à direita. -# -# É assim que o exemplo acima de acesso à head e tail de uma lista funciona. - -# Um pattern match retornará erro quando os lados não conferem, como neste exemplo -# onde as tuplas tem diferentes tamanhos. -# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} - -# Também há binários -<<1,2,3>> # binary - -# Strings e char lists -"hello" # string -'hello' # char list - -# Strings de múltiplas linhas -""" -Strings -de múltiplas -linhas. -""" -#=> "Strings\nde múltiplas\nlinhas" - -# Strings são sempre codificadas em UTF-8: -"héllò" #=> "héllò" - -# Strings são de fato apenas binários, e char lists apenas listas. -<> #=> "abc" -[?a, ?b, ?c] #=> 'abc' - -# `?a` em elixir retorna o valor ASCII para a letra `a` -?a #=> 97 - -# Para concatenar listas use `++`, para binários use `<>` -[1,2,3] ++ [4,5] #=> [1,2,3,4,5] -'hello ' ++ 'world' #=> 'hello world' - -<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> -"hello " <> "world" #=> "hello world" - -# Ranges são representados como `início..fim` (ambos inclusivos) -1..10 #=> 1..10 -menor..maior = 1..10 # Pattern matching pode ser usada em ranges também -[lower, upper] #=> [1, 10] - -## --------------------------- -## -- Operadores -## --------------------------- - -# Matemática básica -1 + 1 #=> 2 -10 - 5 #=> 5 -5 * 2 #=> 10 -10 / 2 #=> 5.0 - -# Em elixir o operador `/` sempre retorna um float. - -# Para divisão de inteiros use `div` -div(10, 2) #=> 5 - -# Para obter o resto da divisão use `rem` -rem(10, 3) #=> 1 - -# Há também operadores booleanos: `or`, `and` e `not`. -# Estes operadores esperam um booleano como primeiro argumento. -true and true #=> true -false or true #=> true -# 1 and true #=> ** (ArgumentError) argument error - -# Elixir também fornece `||`, `&&` e `!` que aceitam argumentos de qualquer tipo. -# Todos os valores exceto `false` e `nil` serão avaliados como true. -1 || true #=> 1 -false && 1 #=> false -nil && 20 #=> nil -!true #=> false - -# Para comparações temos: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` e `>` -1 == 1 #=> true -1 != 1 #=> false -1 < 2 #=> true - -# `===` e `!==` são mais estritos ao comparar integers e floats: -1 == 1.0 #=> true -1 === 1.0 #=> false - -# Podemos comparar também dois tipos de dados diferentes: -1 < :hello #=> true - -# A regra de ordenação no geral é definida abaixo: -# number < atom < reference < functions < port < pid < tuple < list < bit string - -# Ao citar Joe Armstrong nisto: "A ordem de fato não é importante, -# mas que uma ordem total esteja bem definida é importante." - -## --------------------------- -## -- Fluxo de Controle -## --------------------------- - -# expressão `if` -if false do - "Isso nunca será visto" -else - "Isso será" -end - -# Também há `unless` -unless true do - "Isso nunca será visto" -else - "Isso será" -end - -# Lembra do patter matching? Muitas estruturas de fluxo de controle em elixir contam com ela. - -# `case` nos permite comparar um valor com muitos patterns: -case {:um, :dois} do - {:quatro, :cinco} -> - "Isso não corresponde" - {:um, x} -> - "Isso corresponde e vincula `x` a `:dois`" - _ -> - "Isso corresponde a qualquer valor" -end - -# É comum vincular o valor a `_` se não precisamos dele. -# Por exemplo, se apenas a head de uma lista nos interessa: -[head | _] = [1,2,3] -head #=> 1 - -# Para melhor legibilidade podemos fazer o seguinte: -[head | _tail] = [:a, :b, :c] -head #=> :a - -# `cond` nos permite verificar várias condições ao mesmo tempo. -# Use `cond` em vez de aninhar vários `if`'s. -cond do - 1 + 1 == 3 -> - "Nunca serei visto" - 2 * 5 == 12 -> - "Nem eu" - 1 + 2 == 3 -> - "Mas eu serei" -end - -# É comum definir a última condição igual a `true`, que sempre irá corresponder. -cond do - 1 + 1 == 3 -> - "Nunca serei visto" - 2 * 5 == 12 -> - "Nem eu" - true -> - "Mas eu serei (isso é essencialmente um else)" -end - -# `try/catch` é usado para capturar valores que são lançados, também suporta uma -# cláusula `after` que é invocada havendo um valor capturado ou não. -try do - throw(:hello) -catch - message -> "Deu #{mensagem}." -after - IO.puts("Sou o after.") -end -#=> Sou o after -# "Deu :hello" - -## --------------------------- -## -- Módulos e Funções -## --------------------------- - -# Funções Anônimas (repare o ponto) -square = fn(x) -> x * x end -square.(5) #=> 25 - -# Elas também aceitam várias cláusulas e guards. -# Guards permitem ajustes finos de pattern matching, -# sendo indicados pela palavra `when`: -f = fn - x, y when x > 0 -> x + y - x, y -> x * y -end - -f.(1, 3) #=> 4 -f.(-1, 3) #=> -3 - -# Elixir também fornece várias funções embutidas. -# Estas estão disponíveis no escopo atual. -is_number(10) #=> true -is_list("ola") #=> false -elem({1,2,3}, 0) #=> 1 - -# Você pode agrupar algumas funções em um módulo. Dentro de um módulo use `def` -# para definir suas funções. -defmodule Math do - def sum(a, b) do - a + b - end - - def square(x) do - x * x - end -end - -Math.sum(1, 2) #=> 3 -Math.square(3) #=> 9 - -# Para compilar o módulo Math salve-o como `math.ex` e use `elixirc` -# em seu terminal: elixirc math.ex - -# Dentro de um módulo podemos definir funções com `def` e funções privadas com `defp`. -# Uma função definida com `def` pode ser invocada por outros módulos, -# já uma função privada pode ser invocada apenas localmente. -defmodule PrivateMath do - def sum(a, b) do - do_sum(a, b) - end - - defp do_sum(a, b) do - a + b - end -end - -PrivateMath.sum(1, 2) #=> 3 -# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) - -# Declarações de funções também suportam guards cláusulas múltiplas: -defmodule Geometry do - def area({:rectangle, w, h}) do - w * h - end - - def area({:circle, r}) when is_number(r) do - 3.14 * r * r - end -end - -Geometry.area({:rectangle, 2, 3}) #=> 6 -Geometry.area({:circle, 3}) #=> 28.25999999999999801048 -# Geometry.area({:circle, "not_a_number"}) -#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 - -# Devido à imutabilidade, recursão é uma grande parte do elixir -defmodule Recursion do - def sum_list([head | tail], acc) do - sum_list(tail, acc + head) - end - - def sum_list([], acc) do - acc - end -end - -Recursion.sum_list([1,2,3], 0) #=> 6 - -# Módulos do elixir suportam atributos, hpa atributos embutidos e você -# pode também adicionar os seus próprios. -defmodule MyMod do - @moduledoc """ - Este é um atributo embutido em um módulo de exemplo. - """ - - @my_data 100 # Este é um atributo customizado. - IO.inspect(@my_data) #=> 100 -end - -## --------------------------- -## -- Structs e Exceptions -## --------------------------- - -# Structs são extensões no topo de mapas que trazem valores padrão, -# garantias em tempo de compilação e polimorfismo para o Elixir. -defmodule Pessoa do - defstruct nome: nil, idade: 0, peso: 0 -end - -joe_info = %Pessoa{ nome: "Joe", idade: 30, peso: 180 } -#=> %Pessoa{idade: 30, peso: 180, nome: "Joe"} - -# Acessa o valor de nome -joe_info.name #=> "Joe" - -# Atualiza o valor de idade -older_joe_info = %{ joe_info | idade: 31 } -#=> %Pessoa{idade: 31, peso: 180, nome: "Joe"} - -# O bloco `try` com a palavra `rescue` é usado para manipular exceções -try do - raise "algum erro" -rescue - RuntimeError -> "resgatado um erro em tempo de execução" - _error -> "isso resgatará qualquer erro" -end - -# Toda exceção possui uma mensagem -try do - raise "algum erro" -rescue - x in [RuntimeError] -> - x.message -end - -## --------------------------- -## -- Concorrência -## --------------------------- - -# Elixir conta com o modelo de ator para concorrência. Tudo o que precisamos para -# escrever programas concorrentes em elixir são três primitivos: spawning processes, -# sending messages e receiving messages. - -# Para iniciar um novo processo usamos a função `spawn`, a qual leva uma função -# como argumento. -f = fn -> 2 * 2 end #=> #Function -spawn(f) #=> #PID<0.40.0> - -# `spawn` retorna um pid (process identifier), você pode usar esse pid para enviar -# mensagens ao processo. Para envio de mensagens usamos o operador `send`. -# Para tudo isso ser útil precisamos estar aptos a receber mensagens. Isto é -# realizado com o mecanismo `receive`: -defmodule Geometry do - def area_loop do - receive do - {:rectangle, w, h} -> - IO.puts("Area = #{w * h}") - area_loop() - {:circle, r} -> - IO.puts("Area = #{3.14 * r * r}") - area_loop() - end - end -end - -# Compile o módulo e crie um processo que avalie `area_loop` no shell -pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> - -# Envia uma mensagem ao `pid` correspondente a um pattern na declaração de recebimento -send pid, {:rectangle, 2, 3} -#=> Area = 6 -# {:rectangle,2,3} - -send pid, {:circle, 2} -#=> Area = 12.56000000000000049738 -# {:circle,2} - -# O shell também é um processo, você pode usar `self` para obter o pid atual -self() #=> #PID<0.27.0> -``` - -## Referências - -* [Getting started guide](http://elixir-lang.org/getting_started/1.html) da [página do elixir](http://elixir-lang.org) -* [Elixir Documentation](http://elixir-lang.org/docs/master/) -* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) por Dave Thomas -* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) -* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) por Fred Hebert -* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) por Joe Armstrong -- cgit v1.2.3