<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ALOVasconcelos</title>
	<atom:link href="http://alovasconcelos.net/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://alovasconcelos.net/blog</link>
	<description>Blog do Vasconcelos</description>
	<lastBuildDate>Sat, 17 Jul 2010 12:26:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Configurando o ambiente de desenvolvimento em c no Ubuntu Linux</title>
		<link>http://alovasconcelos.net/blog/?p=763</link>
		<comments>http://alovasconcelos.net/blog/?p=763#comments</comments>
		<pubDate>Sat, 17 Jul 2010 12:26:57 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=763</guid>
		<description><![CDATA[Supondo que você pretenda começar a desenvolver em C, C++ ou esteja acompanhando o meu &#60;a href=&#8221;http://groups.google.com/group/alomundo/files&#8221; target=&#8221;_blank&#8221;&#62;Curso Básico de Programação em C para Linux&#60;/a&#62;, esteja com o Ubuntu Linux instalado e mas não saiba por onde começar, aqui vão os comandos que eu uso para &#8220;configurar&#8221; o meu ambiente de desenvolvimento:
sudo apt-get install build-essential [...]]]></description>
			<content:encoded><![CDATA[<p>Supondo que você pretenda começar a desenvolver em C, C++ ou esteja acompanhando o meu &lt;a href=&#8221;http://groups.google.com/group/alomundo/files&#8221; target=&#8221;_blank&#8221;&gt;Curso Básico de Programação em C para Linux&lt;/a&gt;, esteja com o Ubuntu Linux instalado e mas não saiba por onde começar, aqui vão os comandos que eu uso para &#8220;configurar&#8221; o meu ambiente de desenvolvimento:</p>
<p>sudo apt-get install build-essential autogen automake autoconf g++ vim libxext-dev</p>
<p>Este comando instala as bibliotecas básicas para desenvolvimento em C e em C++, além da versão improved do editor de textos VI.</p>
<p>Depois de concluída a instalação, você pode fazer um teste digitando o programa alomundo.c:</p>
<pre code="c">;

/* Alo mundo */
#include &lt;stdio.h&gt;
int main (int argc, char * argv[])
{
printf(“Alô, mundo!\n”);
return 0;
}
</pre>
<p>Para compilar, execute </p>
<p>c++ alomundo.cpp -o alomundo</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=763</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eu voltei&#8230;</title>
		<link>http://alovasconcelos.net/blog/?p=758</link>
		<comments>http://alovasconcelos.net/blog/?p=758#comments</comments>
		<pubDate>Fri, 21 May 2010 17:42:33 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=758</guid>
		<description><![CDATA[Meu blog está de volta, depois de ter sido vítima de hackers. Ainda não consegui recuperá-lo completamente, então vão notar a falta de algumas coisas, como as imagens por exemplo. Aos poucos vou &#8220;reconstruindo&#8221; os posts.
Quando meu site foi hackeado a vontade de desistir foi grande, mas a leitura de alguns comentários me incentivaram. Muito [...]]]></description>
			<content:encoded><![CDATA[<p>Meu blog está de volta, depois de ter sido vítima de hackers. Ainda não consegui recuperá-lo completamente, então vão notar a falta de algumas coisas, como as imagens por exemplo. Aos poucos vou &#8220;reconstruindo&#8221; os posts.</p>
<p>Quando meu site foi hackeado a vontade de desistir foi grande, mas a leitura de alguns comentários me incentivaram. Muito obrigado. Vou tentar não decepciona-los.</p>
<p>Grande abraço.</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=758</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como escrever código Go</title>
		<link>http://alovasconcelos.net/blog/?p=753</link>
		<comments>http://alovasconcelos.net/blog/?p=753#comments</comments>
		<pubDate>Mon, 14 Dec 2009 21:56:32 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=753</guid>
		<description><![CDATA[Introdução
Este documento explica como escrever uma nova package e como testar o código. Ele assume que você tenha instalado Go, usando as instruções de instalação.
N.T. &#8211; Aqui mesmo neste blog, disponibilizei a tradução do tutorial de instalação.
Antes de embarcar em uma mudança de uma package existente ou na criação de uma nova package, é uma [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introdução</strong></p>
<p>Este documento explica como escrever uma nova <strong>package</strong> e como testar o código. Ele assume que você tenha instalado <strong>Go</strong>, usando as <a href="http://golang.org/doc/install.html" target="_blank">instruções de instalação</a>.<br />
N.T. &#8211; Aqui mesmo neste blog, disponibilizei a <a href="http://alovasconcelos.net/blog/?p=473">tradução do tutorial de instalação</a>.</p>
<p>Antes de embarcar em uma mudança de uma <strong>package </strong>existente ou na criação de uma nova <strong>package</strong>, é uma boa idéia enviar uma mensagem à lista de correspondência para que as pessoas saibam o que você pretende fazer. Agindo assim você ajuda a evitar duplicação de esforços e habilitar discussões sobre <em>design</em> antes que haja muito código escrito.</p>
<p><strong>Recursos da comunidade</strong></p>
<p>Para ajuda em tempo real, podem haver usuários ou desenvolvedores em #go-nuts no servidor <a href="http://freenode.net/" target="_blank">Freenode</a> IRC. A lista oficial para discussão da linguagem Go é <a href="http://groups.google.com/group/golang-nuts" target="_blank">Go Nuts</a>.</p>
<p>Bugs podem ser relatados usando o <a href="http://code.google.com/p/go/issues/list" target="_blank">Go issue tracker&#8221;</a>.</p>
<p>Para aqueles que desejem acompanhar o desenvolvimento, existe outra lista, <a href="http://groups.google.com/group/golang-checkins" target="_blank">golang-checkins</a>, que recebe uma mensagem resumindo cada checkin feito no repositório Go.</p>
<p><strong>Criando uma nova package</strong></p>
<p>O código-fonte para a <strong>package </strong>com caminho import x/y é, por convenção, mantida no diretório <strong>$GOROOT/src/pkg/y/y</strong>.</p>
<p><strong>Makefile</strong></p>
<p>Seria bom ter ferramentas específicas<strong> Go</strong> que verificassem os arquivos-fonte para determinar o que montar e em que ordem, mas por enquanto, <strong>Go </strong>usa a ferramenta <strong>GNU make</strong>. Portanto, o primeiro arquivo a criar em uma diretório de uma nova <strong>package </strong>é geralmente<br />
o <strong>Makefile</strong>. A forma básica usada na árvore de fontes de Go é ilustrada por <strong>src/pkg/container/vector/Makefile</strong>:</p>
<pre lang="bash">
include ../../../Make.$(GOARCH)

TARG=container/vector
GOFILES=\
	intvector.go\
	stringvector.go\
	vector.go\

include ../../../Make.pkg
</pre>
<p>Fora da árvore de fontes de <strong>Go </strong>(para <strong>packages </strong>pessoais), a forma padrão é</p>
<pre lang="bash">
include $(GOROOT)/src/Make.$(GOARCH)

TARG=mypackage
GOFILES=\
	my1.go\
	my2.go\

include $(GOROOT)/src/Make.pkg
</pre>
<p>A primeira e a última linha incluem definições padrão e regras. <strong>Packages </strong>mantidas na árvore padrão <strong>Go</strong> usam um caminho relativo (ao invés de <strong>$(GOROOT)/src</strong>) de modo que make trabalhará corretamente mesmo se $(GOROOT) contiver espaços. Isto torna fácil aos programadores experimentar <strong>Go</strong>.<br />
<strong>TARG </strong>é o caminho alvo de instalação para a <strong>package</strong>, a <em>string </em>que clientes usarão para importa-la. Dentro da árvore <strong>Go</strong>, a <em>string </em>deve ser a igual ao diretório no qual o Makefile aparece, como o prefixo <strong>$GOROOT/src/pkg</strong> removido. Fora da árvore <strong>Go</strong>, você pode usar qualquer <strong>TARG </strong>que deseje desde que não conflite com o nome de <strong>packages </strong>padrão <strong>Go</strong>.<br />
Uma convenção comum é usar um nome identificador de primeiro nível para agrupar suas <strong>packages</strong>: <strong>myname/tree</strong>, <strong>myname/filter</strong>, etc. Observe que mesmo que você mantenha suas <strong>packages</strong> fora da árvore <strong>Go</strong>, a execução de &#8220;<strong>make install</strong>&#8221; instalará os binários de sua <strong>package </strong>no local padrão &#8211; <strong>$GOROOT/pkg</strong> &#8211; para facilitar a sua localização.</p>
<p>GOFILES é uma lista de arquivos-fonte a serem compilados para criar a package. O caracter \ no final de cada linha permite quebras a lista em linhas múltiplas para faciliar<br />
a ordenação.<br />
Se você criar um diretório de uma nova <strong>package </strong>na árvore <strong>Go</strong>, adicione-o a lista em<strong> $GOROOT/src/pkg/Makefile</strong> de modo que ele seja incluido na montagem padrão. Então execute:</p>
<pre lang="bash">
cd $GOROOT/src/pkg
./deps.bash
</pre>
<p>para atualizar o arquivo de dependências &#8211; <strong>Make.deps</strong> (Isto acontece automaticamente cada vez que você executa <strong>all.bash</strong> ou <strong>make.bash</strong>).</p>
<p>Se você altera os imports de uma <strong>package </strong>existente, não precisa editar <strong>$GOROOT/src/pkg/Makefile</strong> mas ainda precisará executar <strong>deps.bash</strong> como acima.</p>
<p><strong>Arquivos-fonte Go<br />
</strong><br />
A primeira declaração em cada arquivo-fonte listado no <strong>Makefile </strong>deve ser o nome da <strong>package</strong>, onde &#8220;<strong>nome</strong>&#8221; é o nome padrão da <strong>package </strong>para &#8220;<strong>imports</strong>&#8221; (Todos os arquivos em uma <strong>package </strong>devem usar o mesmo nome). A convenção de <strong>Go </strong>é que o nome da <strong>package </strong>seja o último elemento do caminho do<strong> import</strong>: a <strong>package </strong>importada &#8220;crypto/rot13&#8243; deve ser nomeada rot13. No momento, as ferramentas <strong>Go </strong>impõem uma restrição que nomes de <strong>packages</strong> sejam únicos em todas as<strong> packages</strong> relacionadas a um único binário, mas esta restrição será abolida em breve.</p>
<p><strong>Go</strong> compila todos os arquivos-fonte em uma <strong>package </strong>de uma vez, então um arquivo pode fazer referência a constantes, variáveis, tipos e funções em outro arquivo sem arranjos especiais ou declarações.</p>
<p>Escrever código <strong>Go </strong>limpo e idiomático está além do escopo deste documento. O documento <a href="http://golang.org/doc/effective_go.html" target="_blank">Effective Go</a> é uma introdução a este tópico.</p>
<p><strong>Testando</strong></p>
<p>Go tem um <em>framework </em>de teste peso-leve conhecido como <strong>gotest</strong>. Você escreve um teste criando um arquivo com o nome terminado em <strong>_test.go</strong> que contém funções nomeadas <strong>TestXXX</strong> com a assinatura <strong>func(t *testing.T)</strong>. O <em>framework</em> de teste executa cada uma destas funções; se a função chama uma função de falha como <strong>t.Error </strong>ou f<strong>.Fail</strong>, o teste é considerado como tendo falhado.<br />
A documentação do comando <strong>gotest </strong>e a documentação da <strong>package </strong>testing dão mais detalhes.</p>
<p>Os arquivos *_test.go não devem estar listados no Makefile.</p>
<p>Para executar o teste, execute<strong> make test</strong> ou <strong>gotest </strong>(são equivalentes). Para executar apenas os testes em um único arquivo de teste, por exemplo one_test.go, execute <strong>gotest one_test.go</strong>.</p>
<p>Se sua mudança afeta <em>performance</em>, adicione uma função <em>Benchmark </em>(veja a documentação do comando <strong>gotest</strong>) e execute-a usando <strong>gotest -benchmarks=.</strong>.</p>
<p>Uma vez que seu novo código esteja testado e funcionando, é hora de revisa-lo e submete-lo.</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=753</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 9</title>
		<link>http://alovasconcelos.net/blog/?p=732</link>
		<comments>http://alovasconcelos.net/blog/?p=732#comments</comments>
		<pubDate>Thu, 10 Dec 2009 20:42:07 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=732</guid>
		<description><![CDATA[Multiplexação
[Voltar ao menu]
Multiplexação
Com channels, é possível servir múltiplos clientes goroutines independentes sem escrever
um multiplexador explícito. O truque é enviar ao servidor um channel na mensagem,
o quel será então usado para responder ao sender original.
Um programa cliente-servidor real tem muito código, então aqui está um substituto bastante
simples para ilustrar a idéia. Ele começa definindo um tipo [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="multiplex">Multiplexação</a></h3>
<p>[<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>Multiplexação</p>
<p>Com channels, é possível servir múltiplos clientes goroutines independentes sem escrever<br />
um multiplexador explícito. O truque é enviar ao servidor um channel na mensagem,<br />
o quel será então usado para responder ao sender original.</p>
<p>Um programa cliente-servidor real tem muito código, então aqui está um substituto bastante<br />
simples para ilustrar a idéia. Ele começa definindo um tipo &#8220;request&#8221;, que embute um channel<br />
que será usado para responder.</p>
<pre lang="c" line="9">
    type request struct {
        a, b    int;
        replyc  chan int;
    }
</pre>
<p>O servidor será trivial: ele fará operações simples com inteiros. Aqui está o código<br />
que invoca a operação e responde à requisição:</p>
<pre lang="c" line="14">
    type binOp func(a, b int) int

    func run(op binOp, req *request) {
        reply := op(req.a, req.b);
        req.replyc <- reply;
    }
</pre>
<p>A linha 18 define o nome "binOp" para a função recebendo dois inteiros e<br />
retornando um terceiro.</p>
<p>A rotina "server" executa um loop infinito, recebendo requisições e, para prevenir<br />
bloqueio devido a operações muito demoradas, "starta" uma goroutine para fazer o trabalho de verdade.</p>
<pre lang="c" line="21">
    func server(op binOp, service chan *request) {
        for {
            req := <-service;
            go run(op, req);  // Não espera
        }
    }
</pre>
<p>Construimos um servidor de uma forma familiar, "startando-o" e retornando um channel<br />
conectado a ele:</p>
<pre lang="c" line="28">
    func startServer(op binOp) chan *request {
        req := make(chan *request);
        go server(op, req);
        return req;
    }
</pre>
<p>Aqui está um teste simples. Ele "starta" um servidor com um operador de adição e<br />
envia N requisições sem esperar por suas respostas. Apenas depois de que todas as<br />
requisições enviadas sejam executadas, checa seus resultados.</p>
<pre lang="c" line="34">
    func main() {
        adder := startServer(func(a, b int) int { return a + b });
        const N = 100;
        var reqs [N]request;
        for i := 0; i < N; i++ {
            req := &#038;reqs[i];
            req.a = i;
            req.b = i + N;
            req.replyc = make(chan int);
            adder <- req;
        }
        for i := N-1; i >= 0; i-- {   // Não importa a ordem
            if <-reqs[i].replyc != N + 2*i {
                fmt.Println("fail at", i);
            }
        }
        fmt.Println("done");
    }
</pre>
<p>Um contra-tempo com este programa é que ele não desliga o servidor de forma limpa; quando "main" retorna<br />
existe um número de goroutines prolongadas bloqueadas na comunicação. Para resolver isto, podemos<br />
prover um segundo channel "quit" para o servidor:</p>
<pre lang="c" line="32">
    func startServer(op binOp) (service chan *request, quit chan bool) {
        service = make(chan *request);
        quit = make(chan bool);
        go server(op, service, quit);
        return service, quit;
    }
</pre>
<p>Ele passa o channel quit para a função "server", que o utiliza desta forma:</p>
<pre lang="c" line="21">
    func server(op binOp, service chan *request, quit chan bool) {
        for {
            select {
            case req := <-service:
                go run(op, req);  // Não espera
            case <-quit:
                return;
            }
        }
    }
</pre>
<p>Dentro da função "server", a declaração "select" escolhe qual das múltiplas comunicações<br />
listadas pelos seus "cases" pode continuar. Se todos estiverem bloqueados, aguarda até que um<br />
possa continuar; se vários puderem prosseguir, escolhe um aleatoriamente. Neste exemplo, o<br />
"select" permite ao servidor reconhecer requisições até que receba a mensagem "quit",  no ponto<br />
em que retorna, terminando sua execução.</p>
<p>Tudo que resta é focalizar o channel "quit" no fim de main:</p>
<pre lang="c" line="40">
        adder, quit := startServer(func(a, b int) int { return a + b });
</pre>
<pre lang="c" line="55">
        quit <- true;
</pre>
<p>Existe muito mais sobre programação Go e programação concorrente em geral, mas este "quick tour"<br />
deve lhe oferecer alguns dos princípios básicos.</p>
<p>Bom, esta foi a última parte da minha tradução do Tutorial disponibilizado pela equipe do Go.<br />
Meu inglês anda meio enferrujado, então se alguém puder contribuir sugerindo alterações<br />
no texto, agradeço.</p>
<p>Um forte abraço a todos.</p>
<p> \\// </p>
<p>yIn nI' yISIQ 'ej yIchep</p>
<p>André Luiz de Oliveira Vasconcelos</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=732</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 8</title>
		<link>http://alovasconcelos.net/blog/?p=715</link>
		<comments>http://alovasconcelos.net/blog/?p=715#comments</comments>
		<pubDate>Mon, 07 Dec 2009 22:03:00 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=715</guid>
		<description><![CDATA[
[Voltar ao menu]
Agora chegamos aos processos de comunicação e programação concorrente. É um assunto vasto, então para ser breve, assumimos alguma familiaridade com o tópico.
Um programa clássico neste estilo é a peneira de números primos. (A peneira de Eratosthenes (The sieve of Eratosthenes) é mais eficiente do que o algoritmo aqui apresentado, mas estamos mais [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="primos"></a></h3>
<p>[<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>Agora chegamos aos processos de comunicação e programação concorrente. É um assunto vasto, então para ser breve, assumimos alguma familiaridade com o tópico.</p>
<p>Um programa clássico neste estilo é a peneira de números primos. (A peneira de Eratosthenes (<a href="http://o-que-quer-dizer.blogspot.com/2001/02/sieve-of-eratosthenes-peneira-de.html" target="_blank">The sieve of Eratosthenes</a>) é mais eficiente do que o algoritmo aqui apresentado, mas estamos mais interessados em concorrência do que em algoritmos no momento). Ela (a peneira) funciona pegando uma cadeia de todos os números naturais e introduzindo uma sequência de filtros, uma para cada número primo, para destacar os múltiplos daquele número primo. A cada passo temos uma sequência de filtros dos primos até então, e o próximo número a ser retirado é o próximo primo, o qual dispara a criação do próximo filtro na cadeia.</p>
<p>Aqui está um diagrama de fluxo; cada caixa representa um elemento filtro cuja criação é disparada pelo primeiro número que fluiu dos elementos anteriores.</p>
<p><a href="http://alovasconcelos.net/blog/wp-content/uploads/2009/12/sieve1.gif"><img class="aligncenter size-full wp-image-769" title="sieve" src="http://alovasconcelos.net/blog/wp-content/uploads/2009/12/sieve1.gif" alt="" width="563" height="283" /></a></p>
<p>Para criar uma cadeia de inteiros, usamos um channel Go, o qual, emprestado dos descendentes de CSP, representa um canal de comunicação que pode conectar duas computações concorrentes. Em Go, variáveis channel são referências a um objeto de tempo de execução que coordena a comunicação; como feito com maps e slices, use make para criar um novo channel.</p>
<p>Aqui está a primeira função em progs/sieve.go:</p>
<pre lang="c">    // Envia a sequência 2, 3, 4, ... para o channel ch
    func generate(ch chan int) {
        for i := 2; ; i++ {
            ch &lt;- i  // Envia 'i' para o channel 'ch'
        }
    }</pre>
<p>A função generate envia a sequência 2, 3, 4, 5, &#8230; para seu argumento channer, ch, usando o operador binário de comunicações &lt;-. Operações com channel, bloqueiam, então se não existir um receptor para o valor em ch, a operação esperará até que um (receptor) se torne disponível.</p>
<p>A função filtro tem três argumentos: um channel de entrada, um channel de saída e um número primo. Ela copia valores da entrada para a saída, descartando qualquer coisa divisível pelo número primo. O operador unário de comunicação &lt;- (recebe) recupera o próximo valor no channel.</p>
<pre lang="c">    // Copia os valores do channel in para o channel out,
    // removendo aqueles divisíveis por prime
    func filter(in, out chan int, prime int) {
        for {
            i := &lt;-in;  // Receive value of new variable 'i' from 'in'.
            if i % prime != 0 {
                out &lt;- i  // Send 'i' to channel 'out'.
            }
        }
    }</pre>
<p>O gerador (método generate) e os filtros (método filter) executam concomitantemente. Go tem seu próprio modelo de processos/coroutines, para evitar confusões de notação chamamos processamento concomitante em Go de goroutines. Para &#8220;startar&#8221; uma goroutine, chame a função precedendo a chamada com a palavra-chave go; Isto inicia a função executando em paralelo com o processo corrente mas no mesmo espaço de endereçamento:</p>
<pre lang="c">    go sum(hugeArray); // calcula a soma em background</pre>
<p>Se você quer saber quando o cálculo está pronto, passe um channel o qual pode ser verificado:</p>
<pre lang="c">    ch := make(chan int);
    go sum(hugeArray, ch);
    // ... faça alguma coisa enquanto isso
    result := &lt;-ch;  // espera por e recupera o resultado</pre>
<p>Voltemos à nossa peneira de números primos. Aqui está a forma como a canalização da peneira é costurada:</p>
<pre lang="c">    func main() {
        ch := make(chan int);  // Cria um novo channel.
        go generate(ch);  // Starta generate() como uma goroutine.
        for {
            prime := &lt;-ch;
            fmt.Println(prime);
            ch1 := make(chan int);
            go filter(ch, ch1, prime);
            ch = ch1
        }
    }</pre>
<p>A linha 29 cria o channel inicial e passa ao método generate, o qual então inicia. Como cada número primo sai do channel, um novo filtro é adicionado ao canal e sua saída torna-se um novo valor de ch.</p>
<p>O programa da peneira pode ser forçado a usar um padrão comum em seu estilo de programação. Aqui está uma variante do método generate, retirado de progs/sieve.go:</p>
<pre lang="c">    func generate() chan int {
        ch := make(chan int);
        go func(){
            for i := 2; ; i++ {
                ch &lt;- i
            }
        }();
        return ch;
    }</pre>
<p>Esta versão faz toda a configuração inicial internamente. Ela cria o channel de saída, lança a goroutine executando uma função literal, e retorna o channel ao chamador. Ela é um &#8220;factory&#8221; para execuçaõ concomitante, &#8220;startando&#8221; a goroutine e retornando sua conexão.</p>
<p>A notação de função literal (linhas 12 a 16) permitem-nos construir uma função anônima e chamá-la no mesmo momento. Observe que a variável local ch está disponível para a função literal e existe até mesmo após o retorno do método generate.</p>
<p>A mesma alteração pode ser feita no método filter:</p>
<pre lang="c">    func filter(in chan int, prime int) chan int {
        out := make(chan int);
        go func() {
            for {
                if i := &lt;-in; i % prime != 0 {
                    out &lt;- i
                }
            }
        }();
        return out;
    }</pre>
<p>O loop principal da função sieve torna-se mais simples e clara como resultado, e enquanto estamos nela, vamos transformá-la em um &#8220;factory&#8221; também:</p>
<pre lang="c">    func sieve() chan int {
        out := make(chan int);
        go func() {
            ch := generate();
            for {
                prime := &lt;-ch;
                out &lt;- prime;
                ch = filter(ch, prime);
            }
        }();
        return out;
    }</pre>
<p>Agora a interface principal para a peneira de números primos é um channel de números primos:</p>
<pre lang="c">    func main() {
        primes := sieve();
        for {
            fmt.Println(&lt;-primes);
        }
    }</pre>
<p><a href="http://alovasconcelos.net/blog/?p=732">Continua&#8230;</a></p>
<p>Abraços</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=715</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 7</title>
		<link>http://alovasconcelos.net/blog/?p=704</link>
		<comments>http://alovasconcelos.net/blog/?p=704#comments</comments>
		<pubDate>Wed, 02 Dec 2009 20:41:55 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=704</guid>
		<description><![CDATA[Ordenação
 [Voltar ao menu]
Interfaces provêm uma forma simples de polimorfismo. Elas separam completamente
a definição do que um objeto faz de como ele o faz, permitindo implementações
distintas serem representadas em tempos diferentes pela mesma variável interface.
Como um exemplo, considere este exemplo simples de algoritmo de ordenação, tomado
do arquivo progs/sort.go:

    func Sort(data Interface) {
 [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="sorting"><strong>Ordenação</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>Interfaces provêm uma forma simples de polimorfismo. Elas separam completamente<br />
a definição do que um objeto faz de como ele o faz, permitindo implementações<br />
distintas serem representadas em tempos diferentes pela mesma variável interface.</p>
<p>Como um exemplo, considere este exemplo simples de algoritmo de ordenação, tomado<br />
do arquivo progs/sort.go:</p>
<pre lang="c" line="13">
    func Sort(data Interface) {
        for i := 1; i < data.Len(); i++ {
            for j := i; j > 0 &#038;&#038; data.Less(j, j-1); j-- {
                data.Swap(j, j-1);
            }
        }
    }
</pre>
<p>O código precisa apenas de três métodos, os quais empacotamos na interface de ordenação:</p>
<pre lang="c" line="7">
    type Interface interface {
        Len() int;
        Less(i, j int) bool;
        Swap(i, j int);
    }
</pre>
<p>Podemos aplicar <strong>Sort</strong> a qualquer tipo que implemente <strong>Len</strong>, <strong>Less</strong> e <strong>Swap</strong>. A package <strong>sort</strong> inclui os métodos necessários para permitir ordenação de arrays de inteiros, strings, etc.; aqui está o código para arrays de int:</p>
<pre lang="c" line="33">
    type IntArray []int

 func (p IntArray) Len() int { return len(p); }
 func (p IntArray) Less(i, j int) bool { return p[i] < p[j]; }
 func (p IntArray) Swap(i, j int) { p[i], p[j] = p[j], p[i]; }
</pre>
<p>Aqui vemos métodos definidos para tipos que não sejam structs. Você pode definir métodos para qualquer tipo que defina e nomeie em sua package.</p>
<p>E agora uma rotina para testar, de progs/sortmain.go. Esta rotina utiliza uma função na package sort, omitida aqui em favor da brevidade, para testar se o resultado está ordenado.</p>
<pre lang="c" line="12">
    func ints() {
        data := []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586};
        a := sort.IntArray(data);
        sort.Sort(a);
        if !sort.IsSorted(a) {
            panic()
        }
    }
</pre>
<p>Se temos um novo tipo, o qual desejamos que seja capaz de ser ordenado, tudo do que precisamos é fazê-lo implementar os três métodos para aquele tipo, dessa forma:</p>
<pre lang="c" line="30">
    type day struct {
        num        int;
        shortName  string;
        longName   string;
    }

 type dayArray struct { 37 data []*day; 38 }

 func (p *dayArray) Len() int { return len(p.data); }
 func (p *dayArray) Less(i, j int) bool { return p.data[i].num < p.data[j].num; }
 func (p *dayArray) Swap(i, j int) { p.data[i], p.data[j] = p.data[j], p.data[i]; }
</pre>
<h3><a name="printing"><strong>Impressão</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>Os exemplos de impressão formatada vistos até então foram bem modestos. Nesta seção<br />
falaremos sobre como formatação de I/O (entrada e saída) pode ser bem implementada em<br />
Go.</p>
<p>Vimos simples usos da package <strong>fmt</strong>, que implementa <strong>Printf</strong>, <strong>Fprintf</strong>, e assim por diante.<br />
Dentro da package <strong>fmt</strong>, Printf é declarado com a seguinte assinatura:</p>
<pre lang="c">
	Printf(format string, v ...) (n int, errno os.Error)
</pre>
<p>Aquelas reticências (<strong>...</strong>) representam uma lista variável de argumentos, que em C podem ser manipulados usando-se as macros de <strong>stdarg.h</strong>, mas em Go é passada usando uma variável de interface vazia (<strong>interface {}</strong>) e então desempacotada usando a biblioteca de reflexão. É <em>off-topic</em> (fora do assunto), mas o uso de reflexão ajuda a explicar algumas das belas propriedades do métodos Printf de Go, devido à habilidade do Printf de descobrir o tipo de seus argumentos dinamicamente.</p>
<p>Por exemplo, em C cada formato deve corresponder ao tipo de seu argumento. É mais fácil em muitos casos em Go. Ao invés de "%llud" você pode dizer simplesmente "%d"; Printf "sabe" o tamanho e sinal do inteiro e pode fazer a coisa certa pra você. O trecho de código </p>
<pre lang="c" line="10">
        var u64 uint64 = 1<<64-1;
        fmt.Printf("%d %d\n", u64, int64(u64));
</pre>
<p>imprime</p>
<pre lang="bash">
	18446744073709551615 -1
</pre>
<p>De fato, se você for preguiçoso, o formato "%w" imprimirá, em um estilo simples e apropriado, qualquer valor, mesmo um array ou estrutura. A saída de </p>
<pre lang="c" line="14">
        type T struct { a int; b string };
        t := T{77, "Sunset Strip"};
        a := []int{1, 2, 3, 4};
        fmt.Printf("%v %v %v\n", u64, t, a);
</pre>
<p>é</p>
<pre lang="bash">
 18446744073709551615 {77 Sunset Strip} [1 2 3 4]
</pre>
<p>Você pode descartar toda a formatação se usar Print ou Println ao invés de Printf, Estas rotinas implementam formatação completamente automática. A função Print apenas imprime seus elemetos usando o equivalente de "%v"<br />
enquanto Println insere espaços entre argumentos e adiciona uma quebra de linha. A saída de cada uma destas duas linhas é idêntica, àquela da chamada a Printf feita acima.</p>
<pre lang="c" line="18">
        fmt.Print(u64, " ", t, " ", a, "\n");
        fmt.Println(u64, t, a);
</pre>
<p>Se você tem seu próprio tipo que gostaria que fosse formatado por Printf ou Print, apenas lhe dê um método String() que retorne uma string. As rotinas de impressão, examinarão o valor para verificar o mesmo implementa o método (String) e caso o faça, irá utiliza-lo em lugar de outra formatação. Aqui está um exemplo simples.</p>
<pre lang="c" line="9">
    type testType struct { a int; b string }

 func (t *testType) String() string {
 return fmt.Sprint(t.a) + " " + t.b
 }

 func main() {
 t := &#038;testType{77, "Sunset Strip"};
 fmt.Println(t)
 }
</pre>
<p>Uma vez que testType tem um método String, o formatador default para o tipo o utilizará para produzir a saída</p>
<pre lang="bash">
    77 Sunset Strip
</pre>
<p>Observe que o método String chama Sprint (a variante óbvia de Go que retorna uma string) para poceder sua formatação; formatadores especiais podem usar a biblioteca fmt recursivamente.</p>
<p>Outro recurso de Printf é que o formato "%T" imprimirá a representação em string do tipo de um valor, que pode ser prático quando depurando código polimórfico.</p>
<p>É possível escrever formatos de impressão completamente customizados com flags e precisões e etc, mas isto foge um pouco do escopo, então deixaremos como um exercício de exploração.</p>
<p>Você pode perguntar, contudo, como Printf pode prever se um tipo implementa o método String. Na verdade o que ele faz é perguntar "se" o valor pode ser convertido para uma variável interface<br />
que implementa o método.<br />
Esquematicamente, dado um valor <strong>v</strong>, ele faz isto:</p>
<pre lang="c">
	type Stringer interface {
		String() string
	}

	s, ok := v.(Stringer);  // Test whether v implements "String()"
	if ok {
		result = s.String()
	} else {
		result = defaultOutput(v)
	}
</pre>
<p>O código usa um <em>type assertion</em> ("v.(Stringer)") para testar se o valor armazenado em <strong>v</strong> satisfaz a interface Stringer; se satisfaz, s se tornará uma variável de interface implementando o método e ok será verdadeiro. Nós usamos então a variável de interface para chamar o método. (O padrão ",ok" é a forma Go de testar o sucesso de operações como uma conversão de tipo, atualização de map, comunicações e assim por diante, apesar<br />
disso, esta é a única vez em que aparece neste tutorial).<br />
Se o valor não satisfaz à interface, "ok" será falso (false).</p>
<p>N.T. Mais informações sobre type assertion em <a href="http://alovasconcelos.net/blog/?p=531" target="_blank">Go para Programadores C++ - parte 2</a></p>
<p>Neste trecho de código o nome "Stringer" segue a convenção de adicionar "[e]r" às interfaces descrevendo simples conjuntos de métodos como este.<br />
Um último detalhe. Para completar a coleção, além de Printf etc. e Sprintf etc., existe também Fprintf etc. Diferente de C, o primeiro argumento de FPrintf não é um arquivo. Ao invés disse, é uma variável do tipo io.Write, que é um tipo interface definido na biblioteca io:</p>
<pre lang="c">
	type Writer interface {
		Write(p []byte) (n int, err os.Error);
	}
</pre>
<p>(Esta interface é outro nome convencional, desta vez para Write; Existe também  io.Reader, io.ReadWriter e assim por diante). Deste modo você pode chamar Fprintf para qualquer tipo que implemente um método Write() padrão,<br />
não apenas para arquivos, mas também rede, channels, buffers, o que quer que você deseje.</p>
<p><a href="http://alovasconcelos.net/blog/?p=715">Continua...</a></p>
<p>Abraços</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=704</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 6</title>
		<link>http://alovasconcelos.net/blog/?p=686</link>
		<comments>http://alovasconcelos.net/blog/?p=686#comments</comments>
		<pubDate>Mon, 30 Nov 2009 17:49:01 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Mensagens]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=686</guid>
		<description><![CDATA[Gatos podres
 [Voltar ao menu]
N.T. &#8211; O título original é um tipo de trocadilho com o nome do comando &#8220;cat&#8221; do Unix. A propósito, cat &#8211; o comando &#8211; vem de concatenate (concatenar). Além disso, será implementado aqui uma versão de cat que utiliza um algoritmo de criptografia chamado rot13.
Escrita na package file, aqui está [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="rottingcats"><strong>Gatos podres</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>N.T. &#8211; O título original é um tipo de trocadilho com o nome do comando &#8220;<strong>cat</strong>&#8221; do Unix. A propósito, <strong>cat</strong> &#8211; o comando &#8211; vem de <em>concatenate</em> (concatenar). Além disso, será implementado aqui uma versão de <strong>cat</strong> que utiliza um algoritmo de criptografia chamado <a href="http://pt.wikipedia.org/wiki/ROT13" target="_blank"><strong>rot</strong>13</a>.</p>
<p>Escrita na package file, aqui está uma versão simples do utilitário cat:</p>
<pre lang="c" line="5">
    package main

    import (
           "./file";
           "flag";
           "fmt";
           "os";
    ) 

    func cat(f *file.File) {
        const NBUF = 512;
        var buf [NBUF]byte;
        for {
            switch nr, er := f.Read(&#038;buf); true {
            case nr < 0:
                fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", f.String(), er.String());
                os.Exit(1);
            case nr == 0:  // EOF
                return;
            case nr > 0:
                if nw, ew := file.Stdout.Write(buf[0:nr]); nw != nr {
                    fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", f.String(), ew.String());
                }
            }
        }
    }

    func main() {
        flag.Parse();   // Scans the arg list and sets up flags
        if flag.NArg() == 0 {
            cat(file.Stdin);
        }
        for i := 0; i < flag.NArg(); i++ {
            f, err := file.Open(flag.Arg(i), 0, 0);
            if f == nil {
                fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err);
                os.Exit(1);
            }
            cat(f);
            f.Close();
        }
    }
</pre>
<p>Por enquanto isto deve ser fácil de acompanhar, mas a declaração switch apresenta alguns novos recursos. Como um <em>loop</em> <strong>for</strong>, um if ou switch pode incluir uma declaração de inicialização. O switch na linha 18 usa uma (declaração) para criar as variáveis <strong>nr</strong> e <strong>er</strong> para armazenar o valor de retorno de f.Read(). (O if na linha 25 segue a mesma idéia). A declaração switch é geral: ela avalia os cases do cima para baixo, procurando pelo primeiro <em>case</em> que case (misericória!) com o valor; as expressões case não precisam ser constantes ou mesmo inteiros, desde que todos tenham o mesmo tipo.<br />
Quando o valor do switch for verdadeiro, podemos deixá-lo vazio - como é também a situação em uma declaração for, um valor não informado significa true. De fato, o switch é uma forma de cadeia de if-else. Neste ponto, deve ser mencionado que em declarações switch cada case tem um <strong>break</strong> implícito.</p>
<p>A linha 25 chama Write(), fatiando (em Slices) o buffer de entrada, que  é ele mesmo um Slice. Slices proporcionam a forma padão de manipular buffers de entrada e saída em Go.</p>
<p>Agora façamos uma variação de cat que opcionalmente criptografa sua entrada usando o algoritmo rot13. É fácil de fazer, simplesmente processando os bytes, mas ao invés disso exploraremos a noção de interface de Go.<br />
A subrotina cat utiliza apenas dois métodos de <strong>f</strong>: Read() e String(), então comecemos definindo uma interface que em exatamente estes dois métodos. Aqui está o código do programa cat_rot13.go:</p>
<pre lang="c" line="26">
    type reader interface {
        Read(b []byte) (ret int, err os.Error);
        String() string;
    }
</pre>
<p>Qualquer tipo que tenha os dois métodos de <strong>reader</strong> - indiferente de quaisquer outros métodos que o tipo possa ter - implementa a interface. Uma vez que file.File implementa estes métodos, implementa a interface reader. Podemos forçar a sobrotina cat a aceitar um <strong>reader</strong> ao invés de um <strong>*file.File</strong> e funcionaria bem, mas vamos enfeitar um pouco, primeiro escrevendo um segundo tipo que implementa <strong>reader</strong>, um que encapsula um<strong> reader</strong> existente e criptografa os dados com rot13. Para fazer isto, nós apenas definimos o tipo e implementamos os métodos sem muito código adicional, temos uma segunda implementação da interface <strong>reader</strong>.</p>
<pre lang="c" line="31">
    type rotate13 struct {
        source    reader;
    }

 func newRotate13(source reader) *rotate13 {
     return &#038;rotate13{source}
 }

 func (r13 *rotate13) Read(b []byte) (ret int, err os.Error) {
     r, e := r13.source.Read(b);
     for i := 0; i < r; i++ {
         b[i] = rot13(b[i])
     }
     return r, e
 }

 func (r13 *rotate13) String() string {
     return r13.source.String()
 }
 // fim de rot
</pre>
<p>(A função rot13, chamada na linha 42 é trivial e não vale a pena reproduzi-la aqui.)</p>
<p>Para usar o novo recurso, definimos um <em>flag</em>:</p>
<pre lang="c" line="14">
    var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
</pre>
<p>e a usamos de dentro de uma quase inalterada função cat():</p>
<pre lang="c" line="52">
    func cat(r reader) {
        const NBUF = 512;
        var buf [NBUF]byte;

        if *rot13Flag {
             r = newRotate13(r)
        }
        for {
             switch nr, er := r.Read(&#038;buf); {
             case nr < 0:
                 fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String());
                 os.Exit(1);
             case nr == 0: // EOF
                 return;
             case nr > 0:
                 nw, ew := file.Stdout.Write(buf[0:nr]);
                 if nw != nr {
                      fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String());
                 }
             }
       }
 }
</pre>
<p>(Podemos também empacotar em main e deixar cat() sozinho, exceto pela alteração do tipo de argumento; considere isto como um exercício.) As linhas de 56 até a 58 definem tudo; se o flag rot13 for verdadeiro (true), empacota o <strong>reader</strong> que recebemos dentro de um rotate13 e prossegue. Observe que as variáveis da interface são valores, não ponteiros: o argumento é do tipo <strong>reader</strong>, não <strong>*reader</strong>, embora por trás ele contenha um ponteiro para um <strong>struct</strong>.</p>
<p>Aqui está ele em ação:</p>
<pre lang="bash">
    % echo abcdefghijklmnopqrstuvwxyz | ./cat
    abcdefghijklmnopqrstuvwxyz
    % echo abcdefghijklmnopqrstuvwxyz | ./cat --rot13
    nopqrstuvwxyzabcdefghijklm
    %
</pre>
<p>Fãs de <a href="http://pt.wikipedia.org/wiki/Inje%C3%A7%C3%A3o_de_depend%C3%AAncia" target="_blank"><em>dependency injection</em></a> podem animar-se com quão facilmente interfaces nos permitem substituir a implementação de um descritor de arquivo.</p>
<p>Interfaces são um recurso distinto de Go. Uma interface é implementada por um tipo se o tipo implementa todos os métodos declarados na interface. Isto significa que um tipo pode implementar um número arbitrário de diferentes interfaces. Não existe hierarquia de tipo; as coisas podem ser mais <a href="http://pt.wikipedia.org/wiki/Ad_hoc" target="_blank"><em>ad hoc</em></a>, como vimos com rot13. O tipo file.File implementa reader; ele pode também implementar um writer, ou qualquer outra interface construída a partir de seus métodos que se encaixem na situação atual.<br />
Considere a interface <strong>Empty</strong>:</p>
<pre lang="c">
type Empty interface {}
</pre>
<p>Todo tipo implementa a interface Empty, o que a faz útil para coisas como <em>containers</em>.</p>
<p><a href="http://alovasconcelos.net/blog/?p=704">Continua...</a></p>
<p>Abraço</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=686</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 5</title>
		<link>http://alovasconcelos.net/blog/?p=665</link>
		<comments>http://alovasconcelos.net/blog/?p=665#comments</comments>
		<pubDate>Thu, 26 Nov 2009 01:09:04 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=665</guid>
		<description><![CDATA[Uma Package para I/O (entrada e saída)
 [Voltar ao menu]
A seguir veremos uma simples package para executar entrada e saída para arquivos com o tipo usual de interface de abertura/fechamento/leitura/gravação. Aqui está o começo do arquivo file.go:


    package file

    import (
        "os";
 [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="iopack"><strong>Uma Package para I/O (entrada e saída)</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>A seguir veremos uma simples package para executar entrada e saída para arquivos com o tipo usual de interface de abertura/fechamento/leitura/gravação. Aqui está o começo do arquivo file.go:</p>
<pre lang="c" line="5">

    package file

    import (
        "os";
        "syscall";
    )

    type File struct {
        fd      int;    // número do descritor de arquivo
        name    string; // nome do arquivo na abertura (Open)
    }
</pre>
<p>As primeiras linhas declaram o nome da package &#8211; file &#8211; e então importa duas packages. A package <strong>os</strong> oculta as diferenças entre vários sistemas operacionais para dar uma visão consistente da arquivos e assim por diante; aqui usaremos seus utilitários (da package <strong>os</strong>) de manipulação de erros e reproduzir os rudimentos de sua entrada e saída para arquivos.</p>
<p>O outro item é a package externa e de baixo nível  <strong>syscall</strong>, que provê uma interface primitiva para as chamadas adjacentes ao sistema.</p>
<p>A seguir temos uma definição de tipo: a palavra-chave type introduz uma declaração de tipo, neste caso uma estrutura de dados chamada <strong>File</strong>. Para tornar as cosas um pouco mais interessantes, nosso tipo File inclui o nome do arquivo ao qual o descritor do arquivo se refere.</p>
<p>Como File começa com uma letra maiúscula, o tipo está disponível fora da package, ou seja, por usuários da package. Em Go, a regra sobre visibilidade da informação é simples: se o nome (de um tipo em nível superior, função, método, constante, variável ou de um campo ou método de estrutura) começa com maiúscula, usuários da package podem vê-lo. Caso contrário, o nome e consequentemente a coisa que está sendo nomeada é visível apenas dentro da package onde é declarada. Isto é mais do que uma convenção; a regra é forçada pelo compilador. Em Go, o termo para nomes publicamente visíveis é &#8220;exportado&#8221;.<br />
No caso de File, todos os seus campos começam com letras minúsculas e portanto invisíveis para usuários, mas lhe daremos (a File) em breve alguns métodos com letras maiúsculas.<br />
Primeiro, no entanto, aqui está um<em> factory</em> para criar um File:</p>
<pre lang="c" line="17">
    func newFile(fd int, name string) *File {
        if fd < 0 {
            return nil
        }
        return &#038;File{fd, name}
    }
</pre>
<p>This returns a pointer to a new File structure with the file descriptor and name filled in. This code uses Go's notion of a ''composite literal'', analogous to the ones used to build maps and arrays, to construct a new heap-allocated object. We could write </p>
<p>Isto retorna um ponteiro para uma nova estrutura File com o descritor e o nome do arquivo preenchidos. Este código usa a notação Go de um "literal composto", análogo àqueles usados para construir <em>maps</em> e <em>arrays</em>, para construir um novo objeto alocado na área de <strong>heap</strong>. Poderíamos escrever:</p>
<pre lang="c">
    n := new(File);
    n.fd = fd;
    n.name = name;
    return n
</pre>
<p>mas para estruturas simples como File, é mais fácil retornar o endereço de um literal composto usado apenas uma vez, como é feito aqui na linha 21.</p>
<p>Podemos usar o factory para construir algumas variáveis exportadas familiares do tipo *File:</p>
<pre lang="c" line="30">
    func Open(name string, mode int, perm int) (file *File, err os.Error) {
        r, e := syscall.Open(name, mode, perm);
        if e != 0 {
            err = os.Errno(e);
        }
        return newFile(r, name), err
    }
</pre>
<p>Existe uma série de novidades nestas poucas linhas. Primeiro, Open retorna múltiplos valores, um File e um erro (mais sobre erros em breve). Declaramos o retorno multi-valor como uma lista de declarações entre parênteses; sintaticamente parecem como uma segunda lista de parâmetros. A função syscall.Open também tem um retorno multi-valor, que podemos apanhar com a declaração multi-variável na linha 31; ela declara <strong>r</strong> e <strong>e</strong> para armazenar os dois valores, ambos do tipo int (embora você tenha que dar uma ollhada na package syscall para ver isto). Finalmente, a linha 35 retorna dois valores: um ponteiro para o novo File e um erro. Se <strong>syscall.Open</strong> falhar, o descritor <strong>r</strong> será negativo e <strong>newFile</strong> retornará <strong>nil</strong>.</p>
<p>Sobre estes erros: A biblioteca <strong>os </strong>inclui uma noção geral de erro. É uma boa idéia usar suas facilidades em suas interfaces. como fizemos aqui, para manipulação consistente de erros ao longo de códigos Go. Em <strong>Open</strong>, usamos uma conversão para traduzir inteiros de valor da variável Unix <strong>errno</strong> para um tipo inteiro <strong>os.Errno</strong>, implementado por <strong>os.Error</strong>.</p>
<p>Agora que podemos construir <strong>Files</strong>, precisamos escrever métodos para eles. Para declarar um método de um tipo, definimos uma função para ter um receptor explícito daquele tipo, colocado entre parênteses antes do nome da função. Aqui estão alguns métodos para <strong>*File</strong>, cada um deles declarando uma variável receptora <strong>file</strong>.</p>
<pre lang="c" line="38">
    func (file *File) Close() os.Error {
        if file == nil {
            return os.EINVAL
        }
        e := syscall.Close(file.fd);
        file.fd = -1;  // so it can't be closed again
        if e != 0 {
            return os.Errno(e);
        }
        return nil
    }

 func (file *File) Read(b []byte) (ret int, err os.Error) {
    if file == nil {
      return -1, os.EINVAL
   }
   r, e := syscall.Read(file.fd, b);
   if e != 0 {
    err = os.Errno(e);
   }
   return int(r), err
 }

 func (file *File) Write(b []byte) (ret int, err os.Error) {
   if file == nil {
     return -1, os.EINVAL
   }
   r, e := syscall.Write(file.fd, b);
   if e != 0 {
     err = os.Errno(e);
   }
   return int(r), err
 }

 func (file *File) String() string {
   return file.name
 }
</pre>
<p>Não existe um <strong>this</strong> implícito e a variável receptora deve ser usada para acessar membros da estrutura. Métodos não são declarados dentro da declaração da estrutura propriamente. A declaração da estrutura define apenas dados membros. De fato, métodos podem ser criados por quase qualquer tipo que você declare, como um inteiro ou array, não apenas para estruturas (structs). Veremos um exemplo com arrays mais tarde.</p>
<p>O método String é assim chamado por uma convenção de impressão que descreveremos mais tarde.</p>
<p>Os métodos usam a variável pública os.EINVAL para retornar o (versão os.Error de) código de erro EINVAL do Unix. A biblioteca<strong> os</strong> define um conjunto padrão destes valores de erro.</p>
<p>Podemos agora usar nossa nova package:</p>
<pre lang="c" line="5">
 package main

 import (
 "./file";
 "fmt";
 "os";
 )

func main() {
   hello := []byte{'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n'};
   file.Stdout.Write(hello);
   file, err := file.Open("/does/not/exist", 0, 0);
   if file == nil {
     fmt.Printf("can't open file; err=%s\n", err.String());
     os.Exit(1);
   }
 } 

O "./" no import em "./file" diz ao compilador para usar sua própria package ao invés de alguma coisa do diretório de packages instaladas.

Finalmente podemos executar o programa:
<pre lang="bash">
    % helloworld3
    hello, world
    can't open file; err=No such file or directory
    %
</pre>
<p><a href="http://alovasconcelos.net/blog/?p=686">Continua...</a></p>
<p>Abraço</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=665</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 4</title>
		<link>http://alovasconcelos.net/blog/?p=652</link>
		<comments>http://alovasconcelos.net/blog/?p=652#comments</comments>
		<pubDate>Tue, 24 Nov 2009 00:47:38 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[laboratório]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=652</guid>
		<description><![CDATA[Um Interlúdio sobre Alocação
 [Voltar ao menu]
A maioria dos tipos em Go são valores. Se você tem um int ou um struct ou um array, a atribuição copia o conteúdo do objeto. Para alocar um novo valor, use new(), que retorna um ponteiro para o espaço alocado.

type T struct { a, b int }
var t [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="aloca"><strong>Um Interlúdio sobre Alocação</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p>A maioria dos tipos em <strong>Go</strong> são valores. Se você tem um int ou um struct ou um array, a atribuição copia o conteúdo do objeto. Para alocar um novo valor, use new(), que retorna um ponteiro para o espaço alocado.</p>
<pre lang="c">
type T struct { a, b int }
var t *T = new(T);
</pre>
<p>ou o mais idiomático (socorro!):</p>
<pre lang="c">
t := new(T);
</pre>
<p>Alguns tipos &#8211; <strong>maps</strong>, <strong>slices</strong> e <strong>channels</strong> (veja abaixo) &#8211; tem semântica de referência. Se você está guardando um <strong>slice</strong> ou um <strong>map</strong> e modifica seu conteúdo, outras variáveis fazendo referência ao mesmo dado adjacente &#8220;enxergarão&#8221; a modificação. Para estes três tipos você precisa usar a função interna make():</p>
<pre lang="c">    m := make(map[string]int);</pre>
<p>A declaração inicializa o novo <strong>map</strong>, pronto para armazenar entradas. Se você apenas declara o map, como em</p>
<pre lang="c">    var m map[string]int;</pre>
<p>ela (a declaração) cria uma referência <em>nil</em> que não pode armazenar coisa alguma. Para usar o <strong>map</strong>, você deve primeiro inicializa-lo e referencia-lo, usando make() ou por atribuição a partir de um <strong>map</strong> existente.</p>
<p>Observe que new(T) retorna o tipo *T, enquanto make(T) retorna o tipo T. Se voce (por engano) aloca um objeto de referência com new(), receber um ponteiro para uma referência <em>nil</em>, equivalente a declarar uma variável não inicializada e pegar o seu endereço.</p>
<h3><a name="const"><strong>Um Interlúdio sobre Constantes</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]<br />
Embora inteiros estejam disponíveis em vários tamanhos em <strong>Go</strong>, inteiros constantes não. Não existem constantes como 0LL oo 0&#215;0UL. Ao invés disso, constantes inteiras são interpretadas como valores de grande precisão que podem provocar estouro (overflow) quando são atribuidos a variáveis inteiras com precisão insuficiente para representar o valor.</p>
<pre lang="c">    const hardEight = (1 &lt;&lt; 100) &gt;&gt; 97  // válido</pre>
<p>Há nuances que devem merecer reconsiderações nas longas sentenças da especificação da linguagem, mas aqui estão alguns exemplos ilustrativos:</p>
<pre lang="c">var a uint64 = 0  // a tem tipo uint64, valor 0
    a := uint64(0)    // equivalente; usa a "conversão"
    i := 0x1234       // i assume tipo default: int
    var j int = 1e6   // legal - 1000000 é representável como um int
    x := 1.5          // um float
    i3div2 := 3/2     // divisão inteira - resulta 1
    f3div2 := 3./2.   // divisão de ponto flutuante - resulta 1.5</pre>
<p>Conversões só funcionam para casos simples, como convertendo ints de um sinal ou tamanho para outro e entre nts e floats, mais alguns poucos casos simples. Não existem conversões numéricas automáticas de qualquer tipo em Go, além daquela de fazer constantes terem um tamanho e tipo concreto quando atribuidas a uma variável.</p>
<p><a href="http://alovasconcelos.net/blog/?p=665">Continua&#8230;</a></p>
<p>Abraço</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=652</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Um Tutorial para a Linguagem de Programação Go &#8211; parte 3</title>
		<link>http://alovasconcelos.net/blog/?p=631</link>
		<comments>http://alovasconcelos.net/blog/?p=631#comments</comments>
		<pubDate>Fri, 20 Nov 2009 16:00:13 +0000</pubDate>
		<dc:creator>ALOVasconcelos</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Linguagens de programação]]></category>
		<category><![CDATA[Programação para Linux]]></category>

		<guid isPermaLink="false">http://alovasconcelos.net/blog/?p=631</guid>
		<description><![CDATA[Um Interlúdio sobre Tipos
 [Voltar ao menu]
Go possui alguns tipos familiares como int e float, que representam valores de tamanho apropriado para a máquina. Também define tipos de tamanhos explícitos com int8, float64 e assim por diante, além de tipos inteiros sem sinal, como uint, uint32, etc. Estes são tipos distintos; mesmo se int e [...]]]></description>
			<content:encoded><![CDATA[<h3><a name="tipos"><strong>Um Interlúdio sobre Tipos</strong></a></h3>
<p><a name="intro"><strong></strong></a> [<a href="http://alovasconcelos.net/blog/?p=525#top">Voltar ao menu</a>]</p>
<p><strong>Go</strong> possui alguns tipos familiares como <strong>int</strong> e <strong>float</strong>, que representam valores de tamanho apropriado para a máquina. Também define tipos de tamanhos explícitos com <strong>int8</strong>, <strong>float64 </strong>e assim por diante, além de tipos inteiros sem sinal, como <strong>uint</strong>, <strong>uint32</strong>, etc. Estes são tipos distintos; mesmo se int e int32 tenham ambos o 32 bits de tamanho, eles não são do mesmo tipo. Existe também um <strong>byte</strong>, sinônimo para <strong>uint8</strong>, que é o tipo de elemento para strings.</p>
<p>N.T. &#8211; em algumas linguagens, o tamanho ocupado em memória por dados de cada tipo, varia de acordo com a arquitetura da máquina. Em Go, podemos usar tipos com tamanhos fixos, independentes portanto da arquitetura, como int8, por exemplo.</p>
<p>Falando de string, este é um tipo interno também. Strings são valores imutáveis &#8211; eles não são apenas arrays de valores do tipo byte. Uma vez que tenha montado um valor string, você não pode altera-lo, embora &#8211; é claro &#8211; possa mudar uma variável string simplesmente atribuindo a ela um novo valor. Este trecho de código de strings.go é um código válido:</p>
<pre lang="c">s := "hello";
if s[1] != 'e' { os.Exit(1) }
s = "good bye";
var p *string = &#038;s;
*p = "ciao";</pre>
<p>Contudo, as declarações seguintes são inválidas, porque podem modificar um valor string:</p>
<pre lang="c">s[0] = 'x';
(*p)[1] = 'y';</pre>
<p>Em termos de C++, strings Go são um pouco como constantes strings, enquanto que ponteiros são análogos a referências a constantes string.<br />
Sim, os ponteiros existem. Contudo, Go simplifica um pouco o uso deles.</p>
<p>Arrays são declarados assim:</p>
<pre lang="c">var arrayOfInt [10]int;</pre>
<p>Arrays, como strings, são valores, mas são mutáveis. Isto difere do C, no qual  arrayOfInt seria usado como um ponteiro para int. Em Go, como arrays são valores, é importante (e útil) falar sobre ponteiros para arrays.<br />
O tamanho do array é parte do seu tipo; contudo, pode-se declarar uma variável slice, para a qual pode-se atribuir um ponteiro para qualquer array com o mesmo tipo de elemento ou &#8211; muito mais comumente &#8211; uma expressão slice na forma <strong>a[low : high]</strong>, representando o <em>subarray</em> indexado por <strong>low </strong>até <strong>high-1</strong>. Slices parecem muito com arrays, mas não têm um tamanho explícito ([] versus [10]) e fazem referência a um segmento de um subjacente, frequentemente anônimo, array simples. Slices múltiplos podem compartilhar dados se eles representarem partes de um mesmo array; arrays múltplos nunca podem compartilhar dados.</p>
<p>Slices são mais comuns em programas Go do que arrays simples; eles são mais flexíveis, têm referência semântica e são eficientes. O que falta é o controle preciso do esquema de armazenamento de um array simples; se você quer ter uma centena de elementos de um array armazenados dentro da sua estrutura, deve usar um array simples.<br />
Ao passar um array para uma função, quase sempre você desejará declarar o parâmetro formal como um slice. Quando você chamar a função, pegue o endereço do array e Go criará (eficientemente) a referência para um slice e o passará.<br />
Usando slices, pode-se escrever esta função (do programa sum.go &#8211; N.T. &#8211; disponível no diretório go/doc/progs):</p>
<pre lang="c">func sum(a []int) int {   // retorna um int
     s := 0;
     for i := 0; i < len(a); i++ {
         s += a[i]
     }
     return s
}</pre>
<p>e chama-la da segunte forma:</p>
<pre lang="c">     s := sum(&#038;[3]int{1,2,3});  // um slice do array é passado para a função sum</pre>
<p>Note como o tipo de retorno (<strong>int</strong>) é definido para a função sum, declarando-o depois da lista de parâmetros.<br />
A expressão<strong> [3]int{1,2,3}</strong> - um tipo seguido de uma expressão entre chaves - é um construtor para o valor, neste caso um array de 3 ints. Colocar um <strong>&#038;</strong> (ampersand) na frente, fornece o endereço de uma única instância do valor. Passamos o ponteiro para sum() promovendo-o (implicitamente)  para um slice.</p>
<p>Se você está criando um array simples, mas quer que o compilador conte seus elementos para você, use <strong>...</strong> como tamanho do array:</p>
<pre lang="'c"> s := sum(&#038;[...]int{1,2,3});</pre>
<p>Na prática, no entanto, a não ser que você seja muito meticuloso sobre o esquema de armazenamento dentro de uma estrutura de dados, um slice por si mesmo - usando colchetes e sem &#038; - é tudo de que você precisa:</p>
<pre lang="c">    s := sum([]int{1,2,3});</pre>
<p>Existem também os maps, os quais você pode inicializar assim:</p>
<pre lang="c">m := map[string]int{"one":1 , "two":2}</pre>
<p>A função interna <strong>len()</strong>, que retorna o número de elementos, faz sua primeira aparição em sum. Ela trabalha com strings, arrays, slices, maps e channels.<br />
A propósito, outra cosa que funciona com strings, arrays, slices, maps e channels é a cláusula range em <em>loops </em>for. Ao invés de escrever</p>
<pre lang="c">for i := 0; i < len(a); i++ { ... }</pre>
<p>parao iterar pelos elementos de um slice (ou map, ou...), podemos escrever</p>
<pre lang="c">for i, v := range a { ... }</pre>
<p>Isto atribui a <strong>i</strong> o índice do array e a <strong>v</strong> o valor de sucessivo elementos do objeto do <strong>range</strong>. Veja o documento <a href="http://golang.org/doc/effective_go.html">Effective Go</a> para mais exemplos de seu uso (do range).</p>
<p>N.T. Este utilização de range, assemelha-se à estrutura <strong>foreach</strong> encontrada em algumas linguagens de programação. Está nos meus planos, se conseguir tempo para isso, a tradução do documento <a href="http://golang.org/doc/effective_go.html">Effective Go</a> também.</p>
<p><a href="http://alovasconcelos.net/blog/?p=652">Continua...</a></p>
<p>Abraço</p>
]]></content:encoded>
			<wfw:commentRss>http://alovasconcelos.net/blog/?feed=rss2&amp;p=631</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

