├── .gitignore ├── AUTHORS ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── LICENSE ├── README ├── TODO ├── TRANSLATE ├── app.yaml ├── codereview.cfg ├── content ├── basics.article ├── basics │ ├── basic-types.go │ ├── constants.go │ ├── exported-names.go │ ├── functions-continued.go │ ├── functions.go │ ├── imports.go │ ├── multiple-results.go │ ├── named-results.go │ ├── numeric-constants.go │ ├── packages.go │ ├── short-variable-declarations.go │ ├── type-conversions.go │ ├── type-inference.go │ ├── variables-with-initializers.go │ ├── variables.go │ └── zero.go ├── concurrency.article ├── concurrency │ ├── buffered-channels.go │ ├── channels.go │ ├── default-selection.go │ ├── exercise-equivalent-binary-trees.go │ ├── exercise-web-crawler.go │ ├── goroutines.go │ ├── mutex-counter.go │ ├── range-and-close.go │ └── select.go ├── content_test.go ├── flowcontrol.article ├── flowcontrol │ ├── defer-multi.go │ ├── defer.go │ ├── exercise-loops-and-functions.go │ ├── for-continued.go │ ├── for-is-gos-while.go │ ├── for.go │ ├── forever.go │ ├── if-and-else.go │ ├── if-with-a-short-statement.go │ ├── if.go │ ├── switch-evaluation-order.go │ ├── switch-with-no-condition.go │ └── switch.go ├── img │ ├── newton.png │ └── tree.png ├── methods.article ├── methods │ ├── empty-interface.go │ ├── errors.go │ ├── exercise-errors.go │ ├── exercise-images.go │ ├── exercise-reader.go │ ├── exercise-rot-reader.go │ ├── exercise-stringer.go │ ├── images.go │ ├── indirection-values.go │ ├── indirection.go │ ├── interface-values-with-nil.go │ ├── interface-values.go │ ├── interfaces-are-satisfied-implicitly.go │ ├── interfaces.go │ ├── methods-continued.go │ ├── methods-funcs.go │ ├── methods-pointers-explained.go │ ├── methods-pointers.go │ ├── methods-with-pointer-receivers.go │ ├── methods.go │ ├── nil-interface-values.go │ ├── reader.go │ ├── stringer.go │ ├── type-assertions.go │ └── type-switches.go ├── moretypes.article ├── moretypes │ ├── append.go │ ├── array.go │ ├── exercise-fibonacci-closure.go │ ├── exercise-maps.go │ ├── exercise-slices.go │ ├── function-closures.go │ ├── function-values.go │ ├── making-slices.go │ ├── map-literals-continued.go │ ├── map-literals.go │ ├── maps.go │ ├── mutating-maps.go │ ├── nil-slices.go │ ├── pointers.go │ ├── range-continued.go │ ├── range.go │ ├── slice-bounds.go │ ├── slice-len-cap.go │ ├── slice-literals.go │ ├── slices-of-slice.go │ ├── slices-pointers.go │ ├── slices.go │ ├── struct-fields.go │ ├── struct-literals.go │ ├── struct-pointers.go │ └── structs.go ├── welcome.article └── welcome │ ├── hello.go │ └── sandbox.go ├── gotour ├── appengine.go ├── fmt.go ├── local.go └── tour.go ├── pic └── pic.go ├── reader └── validate.go ├── solutions ├── README ├── binarytrees.go ├── binarytrees_quit.go ├── errors.go ├── fib.go ├── http.go ├── image.go ├── loops.go ├── maps.go ├── rot13.go ├── slices.go ├── stringers.go └── webcrawler.go ├── static ├── css │ └── app.css ├── img │ ├── favicon.ico │ └── gopher.png ├── js │ ├── app.js │ ├── controllers.js │ ├── directives.js │ ├── services.js │ └── values.js ├── lib │ ├── angular-ui.min.js │ ├── angular.min.js │ ├── codemirror │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── README.md │ │ ├── lib │ │ │ ├── codemirror.css │ │ │ └── codemirror.js │ │ └── mode │ │ │ └── go │ │ │ └── go.js │ ├── jquery-ui.min.js │ └── jquery.min.js └── partials │ ├── editor.html │ ├── feedback-button.html │ ├── lesson.html │ ├── list.html │ ├── toc-button.html │ └── toc.html ├── template ├── action.tmpl └── index.tmpl ├── tools ├── map.sh └── mapping.old ├── tree └── tree.go └── wc └── wc.go /.gitignore: -------------------------------------------------------------------------------- 1 | last-change 2 | *.orig 3 | *.rej 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Go 2 | 3 | Go is an open source project. 4 | 5 | It is the work of hundreds of contributors. We appreciate your help! 6 | 7 | 8 | ## Filing issues 9 | 10 | When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: 11 | 12 | 1. What version of Go are you using (`go version`)? 13 | 2. What operating system and processor architecture are you using? 14 | 3. What did you do? 15 | 4. What did you expect to see? 16 | 5. What did you see instead? 17 | 18 | General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. 19 | The gophers there will answer or ask you to file an issue if you've tripped over a bug. 20 | 21 | ## Verifying changes during development 22 | 23 | In order to verify changes to the slides or code examples while developing 24 | locally compile with your local toolchain: 25 | 26 | $ go install golang.org/x/tour/gotour 27 | $ $GOPATH/bin/gotour 28 | 29 | ## Running the App Engine version locally 30 | 31 | To view the App Engine version of the slides while developing locally, install 32 | the [Go App Engine SDK](https://cloud.google.com/appengine/downloads?hl=en) 33 | and then: 34 | 35 | $ cd $GOPATH/src/golang.org/x/tour 36 | $ $SDK_PATH/dev_appserver.py . 37 | 38 | The App Engine version runs code examples against the service at play.golang.org. 39 | To verify changes to the code examples you must use your local toolchain to compile 40 | and run `gotour` locally. 41 | 42 | ## Contributing code 43 | 44 | Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) 45 | before sending patches. 46 | 47 | **We do not accept GitHub pull requests** 48 | (we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). 49 | 50 | Unless otherwise noted, the Go source files are distributed under 51 | the BSD-style license found in the LICENSE file. 52 | 53 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is Go Tour, an introduction to the Go programming language. 2 | 3 | To install the tour locally, first install Go, then run: 4 | 5 | $ go get golang.org/x/tour/gotour 6 | $ cd $GOPATH/bin 7 | $ ./gotour 8 | 9 | Unless otherwise noted, the go-tour source files are distributed 10 | under the BSD-style license found in the LICENSE file. 11 | 12 | Contributions should follow the same procedure as for the Go project: 13 | http://golang.org/doc/contribute.html 14 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | This file lists topics that already exist (prefixed by *) and topics that 2 | should be added (prefixed by -). It should be kept up-to-date with tour.article. 3 | 4 | * Hello, 世界 5 | * Go local 6 | * Packages 7 | * Imports 8 | - "Imported but not used" errors (later perhaps) 9 | * Exported names 10 | * Functions 11 | * Functions continued 12 | * Multiple results 13 | * Named results 14 | - Variables (single declaration first) 15 | * Variables 16 | * Variables with initializers 17 | * Short variable declarations 18 | * Basic types 19 | * Type inference 20 | * Type conversions 21 | * Zero values 22 | * Constants 23 | * Numeric Constants 24 | * For 25 | * For continued 26 | * For is Go's "while" 27 | * Forever 28 | * If 29 | * If with a short statement 30 | * If and else 31 | * Exercise: Loops and Functions 32 | * Structs 33 | * Struct Fields 34 | * Pointers 35 | * Struct Literals 36 | * The new function 37 | * Arrays 38 | * Slices 39 | * Slicing slices 40 | * Making slices 41 | * Append 42 | - Copy 43 | * Nil slices 44 | * Range 45 | * Range continued 46 | - The blank identifier 47 | - Slices of slices. 48 | * Exercise: Slices 49 | * Maps 50 | * Map literals 51 | * Map literals continued 52 | * Mutating Maps 53 | - Maps and range 54 | * Exercise: Maps 55 | * Function values 56 | * Function closures 57 | * Exercise: Fibonacci closure 58 | * Switch 59 | * Switch evaluation order 60 | * Switch with no condition 61 | - Complex numbers 62 | * Advanced Exercise: Complex cube roots 63 | - the type keyword 64 | * Methods and Interfaces 65 | * Methods 66 | * Methods continued 67 | * Methods with pointer receivers 68 | * Interfaces 69 | * Interfaces are satisfied implicitly 70 | - Interface assignment 71 | - Empty interface 72 | * Errors 73 | * Exercise: Errors 74 | * Web servers 75 | * Exercise: HTTP Handlers 76 | * Images 77 | * Exercise: Images 78 | * Exercise: Rot13 Reader 79 | - Sort (see sort package examples) 80 | - Exercise: Sort 81 | - Embedding 82 | - Exercise: Embedding (sort by different fields) 83 | - Type assertion 84 | - Type switch 85 | - Exercise: Visitor (walk a tree?) 86 | * Concurrency 87 | * Goroutines 88 | * Channels 89 | * Buffered Channels 90 | * Range and Close 91 | * Select 92 | * Default Selection 93 | * Exercise: Equivalent Binary Trees 94 | * Exercise: Equivalent Binary Trees 95 | * Exercise: Web Crawler 96 | - More language features 97 | * Defer 98 | - Panic and recover 99 | - init functions 100 | - Tools 101 | - Godoc 102 | - Gofmt 103 | * Where to Go from here... 104 | 105 | -------------------------------------------------------------------------------- /TRANSLATE: -------------------------------------------------------------------------------- 1 | Translating the Tour 2 | 3 | A Tour of Go is a Go program that runs as a stand-alone web server or 4 | an App Engine app. The version available at tour.golang.org is run from 5 | App Engine. There are several localized versions of the tour, such as 6 | this Chinese translation, also running on App Engine: 7 | 8 | http://go-tour-zh.appspot.com 9 | 10 | The Tour contains a slide named "Go local", which lists several of 11 | these translations. If you are a native speaker of a language not on 12 | that list and have some experience with Go, please consider providing 13 | a translation of the Tour in your own language. 14 | 15 | To translate the tour: 16 | 17 | 1. Translate the files in content/ 18 | 2. Provide localized version for the UI strings in static/js/values.js 19 | 3. Sign up to App Engine and create an app named go-tour-LL, 20 | where LL is the two-letter country code that applies best 21 | to your chosen language. (This shouldn't cost you anything; 22 | the Tour App usually runs inside App Engine's free quota.) 23 | 4. Deploy your version of the Tour to that app. 24 | 5. Announce to golang-nuts@googlegroups.com 25 | 26 | The Tour content changes occasionally, and you should keep your 27 | translation up to date. To follow the development of the tour, 28 | subscribe to the go-tour-commits mailing list: 29 | 30 | https://groups.google.com/group/go-tour-commits 31 | 32 | All new commits to the go-tour repository are mailed there. 33 | 34 | Finally, if you have any questions about the Tour or Go, 35 | please mail golang-nuts@googlegroups.com. 36 | -------------------------------------------------------------------------------- /app.yaml: -------------------------------------------------------------------------------- 1 | application: go-tour-turkish 2 | version: 1 3 | runtime: go 4 | api_version: go1 5 | 6 | default_expiration: "7d" 7 | 8 | handlers: 9 | 10 | # Keep these static file handlers in sync with gotour/local.go. 11 | - url: /favicon.ico 12 | static_files: static/img/favicon.ico 13 | upload: static/img/favicon.ico 14 | secure: always 15 | - url: /content/img 16 | static_dir: content/img 17 | secure: always 18 | - url: /static 19 | static_dir: static 20 | application_readable: true 21 | secure: always 22 | 23 | - url: /(.*|list|lesson/.*|compile|fmt|script\.js) 24 | script: _go_app 25 | secure: always 26 | 27 | nobuild_files: (solutions|content)/.* 28 | -------------------------------------------------------------------------------- /codereview.cfg: -------------------------------------------------------------------------------- 1 | issuerepo: golang/go 2 | -------------------------------------------------------------------------------- /content/basics.article: -------------------------------------------------------------------------------- 1 | Paketler, değişkenler ve fonksiyonlar 2 | Bir programının temel bileşenlerini öğrenin. 3 | 4 | Go Yazarları Sunar 5 | https://golang.org 6 | 7 | * Paketler 8 | 9 | Her Go programı paketlerden oluşur. 10 | 11 | Programlar `main` paketinde çalışmaya başlar. 12 | 13 | Bu örnek program `"fmt"` ve `"math/rand"` paketlerinin yolunu içe aktararak ("import") kullanıyor. 14 | 15 | Geleneksel olarak, paket isimleri import yolunun son elementi ile isimlendirilir. Örneğin, `"math/rand"` paketi, `package`rand` deyimi ile başlayan dosyaları kapsar. 16 | 17 | #appengine: *Not:* Bu programların yürütüldüğü ortamda rastgelelik olmadığı için 18 | #appengine: örnek program her çalıştırıldığında `rand.Intn` aynı sayıyı döndürecektir. 19 | #appengine: 20 | #appengine: (Farklı bir sayı görmek için, sayı üreticisini besleyin; bkz. [[https://golang.org/pkg/math/rand/#Seed][`rand.Seed`]]) 21 | 22 | .play basics/packages.go 23 | 24 | * İçe Aktarımlar 25 | 26 | Bu kod, içe aktarılan paketleri, parantezlenmiş ve parçalara ayrılmış import deyimi şeklinde gruplar. 27 | 28 | Ayrıca çoklu import deyimleri de kullanabilirsiniz: 29 | 30 | import "fmt" 31 | import "math" 32 | 33 | Fakat parçalara ayrılmış import deyimi kullanımı daha güzel bir görünüm sunar. 34 | 35 | .play basics/imports.go 36 | 37 | * Dışa Aktarılan İsimler 38 | 39 | Go'da, dışa aktarılmış bir isim büyük harf ile başlar. 40 | Örneğin, `Pizza` dışa aktarılmış bir isimdir, tıpkı `math` paketi tarafından ithal edilen `Pi` gibi. 41 | 42 | `pizza` ve `pi` büyük harfle başlamadığından dışa aktarılan isimler değildir. 43 | 44 | Bir paket içe aktarıldığında, pakette sadece dışa aktarılmış isimleri kullanabilirsiniz. 45 | "Dışa aktarılmamış" isimler paketin dışından erişilemez. 46 | 47 | Yandaki kodu çalıştırın. Hata iletisine dikkat edin. 48 | 49 | Hatayı düzeltmek için `math.pi` yi `math.Pi` şeklinde değiştirip yeniden çalıştırın. 50 | 51 | .play basics/exported-names.go 52 | 53 | * Fonksiyonlar 54 | 55 | Bir fonksiyon bir veya birden fazla sayıda argüman alabileceği gibi hiç argüman almayabilir. 56 | 57 | Bu örnekte, `add` fonksiyonu `int` türünde iki parametre alıyor. 58 | 59 | Değişken türünün değişken adından _sonra_ geldiğine dikkat edin. 60 | 61 | (Değişken türlerinin neden bu şekilde tanımlandıkları hakkında daha fazla bilgi için; [[https://blog.golang.org/gos-declaration-syntax][Go dilinde bildirim sözdizimi]] makalesine bakın.) 62 | 63 | .play basics/functions.go 64 | 65 | * Fonksiyonlar devam 66 | 67 | İki ya da daha fazla ardışık fonksiyon parametresi aynı türde ise tür bilgisini, en sonda bulunan hariç, diğer parametreler için belirtmeseniz de olur. 68 | 69 | Bu örnekte 70 | 71 | x int, y int 72 | 73 | fonksiyon parametrelerini şöyle kısalttık: 74 | 75 | x, y int 76 | 77 | .play basics/functions-continued.go 78 | 79 | * Çoklu sonuçlar 80 | 81 | Bir fonksiyon herhangi bir sayıda sonuç döndürebilir. 82 | 83 | Örnekteki `swap` fonksiyonu, dizgi ("string") türünde iki sonuç döndürüyor. 84 | 85 | .play basics/multiple-results.go 86 | 87 | * Adlandırılmış sonuçlar 88 | 89 | Go'nun sonuç değerleri aynı bir değişken gibi adlandırılabilir. Böyle yapıldığında değişken sanki fonksiyonun başında tanımlanmış gibi muamele görür. 90 | 91 | Sonuçlar manalarına, işlevlerine göre adlandırılmalıdır. 92 | 93 | Argümansız bir `return` deyimi adlandırılmış sonuç değerlerini döndürür. Bu "çıplak" return olarak bilinir. 94 | 95 | Çıplak return deyimleri, aynı örnekteki gibi, sadece kısa fonksiyonlarda kullanılmalıdır. Uzun fonksiyonlarda kullanılırlarsa kodun okunabilirliğini azaltırlar. 96 | 97 | .play basics/named-results.go 98 | 99 | * Değişkenler 100 | 101 | `var` deyimi değişkenler tanımlamaya yarar. Ve tıpkı fonksiyon argümanlarında olduğu gibi tür bilgisi sona yazılır. 102 | 103 | `var` deyimi paket veya fonksiyon düzeyinde olabilir. Biz bu örnekte ikisini de görüyoruz. 104 | 105 | .play basics/variables.go 106 | 107 | * Değişkenleri ilklendirme 108 | 109 | Bir `var` deyimi her bir değişken için bir ilklendirme değeri içerebilir. 110 | 111 | Eğer bir ilklendirme mevcut ise tür tanımlaması atlanabilir. Bu halde değişken, ilklendirme değeri ile aynı türde olacaktır. 112 | 113 | .play basics/variables-with-initializers.go 114 | 115 | * Kısaltılmış değişken bildirimleri 116 | 117 | Bir fonksiyon içerisinde, türü belirtilmiş bir `var` bildirimi yerine `:=` kısa atama deyimi kullanılabilir. 118 | 119 | Fonksiyon alanının dışında, her yapı bir anahtar kelime (`var`, `func` vs.) ile başlar ve `:=` yapısını kullanmak mümkün değildir. 120 | 121 | .play basics/short-variable-declarations.go 122 | 123 | * Basit türler 124 | 125 | Go'nun basit türleri şunlardır 126 | 127 | bool 128 | 129 | string 130 | 131 | int int8 int16 int32 int64 132 | uint uint8 uint16 uint32 uint64 uintptr 133 | 134 | byte // diğer adıyla uint8 135 | 136 | rune // diğer adıyla int32 137 | // Unicode karakter kodlarını ifade eder 138 | 139 | float32 float64 140 | 141 | complex64 complex128 142 | 143 | Bu örnekte birçok çeşit türden değişken tanımlanmıştır. 144 | Değişken tanımlamaları, import deyiminde de, olduğu gibi bloklara ayrılmış olarak yapılabilir. 145 | 146 | `int`, `uint` ve `uintptr` veri türleri genellikle 32-bit sistemlerde 32 bit, 64-bit sistemlerde 64 bit genişliğindedir. 147 | Bir tamsayı değeri gerektiğinde, boyutlandırılmış veya işaretsiz bir tamsayı türü kullanmanızı gerektiren özel bir neden olmadığı sürece `int` kullanmalısınız. 148 | 149 | .play basics/basic-types.go 150 | 151 | * Sıfır değerleri 152 | 153 | İlklendirilmemiş her değişken başlangıç değeri olarak kendi "sıfır değeri"ni alır. 154 | 155 | Sıfır değerleri şunlardır: 156 | 157 | - Sayı türleri için `0`, 158 | - Mantıksal (boolean) tür için `false` 159 | - Dizgi (string) türü için `""` (boş dizgi) 160 | 161 | .play basics/zero.go 162 | 163 | * Tür dönüşümleri 164 | 165 | `T(v)` ifadesi `v` değerini `T` türüne dönüştürür. 166 | 167 | Bazı sayısal dönüşümler: 168 | 169 | var i int = 42 170 | var f float64 = float64(i) 171 | var u uint = uint(f) 172 | 173 | Veya basitçesi: 174 | 175 | i := 42 176 | f := float64(i) 177 | u := uint(f) 178 | 179 | Go'da türdeş olmayan ögeler arasında gerçekleşen atamalarda, C dilinden farklı olarak, açık dönüşüm yapılması gerekir. 180 | Örnekteki `float64` veya `uint` dönüşümlerini kaldırmayı deneyin ve ne olduğunu gözlemleyin. 181 | 182 | .play basics/type-conversions.go 183 | 184 | * Tür çıkarımı 185 | 186 | Eğer bir değişken türü belirtilmeden tanımlanırsa (yani `:=` sözdizimi veya `var` ifade sözdizimi kullanılarak), değişkenin türünü sağ taraftaki değer belirler. 187 | 188 | Tanımlamanın sağ tarafı türü belirli olan bir değişken ise, yeni değişkenimiz bu tür ile aynı türe sahip olur: 189 | 190 | var i int 191 | j := i // j int türünden olur 192 | 193 | Fakat sağ taraf türü belirtilmemiş bir sayısal sabit ise, yeni değişken sabitin hassasiyet seviyesine göre `int`, `float64` veya `complex128` türlerinden biri olarak belirlenir: 194 | 195 | i := 42 // int 196 | f := 3.142 // float64 197 | g := 0.867 + 0.5i // complex128 198 | 199 | Örnek koddaki `v` değerinin başlangıç değerini değiştirin ve girdiğiniz değerlerin türün belirlenmesindeki etkisini gözlemleyin. 200 | 201 | .play basics/type-inference.go 202 | 203 | * Sabitler 204 | 205 | Sabitler de değişkenler ile aynı şekilde bildirilir ancak sabitler bildirilirken `const` anahtar kelimesi kullanılır. 206 | 207 | Sabitler; karakter, dizgi ("string"), mantıksal ("boolean") ya da sayısal değerler alabilir. 208 | 209 | Sabitler `:=` operatörü kullanılarak bildirilemezler. 210 | 211 | .play basics/constants.go 212 | 213 | * Sayısal Sabitler 214 | 215 | Sayısal sabitler yüksek hassasiyetli _değerlerdir_. 216 | 217 | Tür bilgisi olmayan bir sabit, bağlamının gerektirdiği "tür"den olur. 218 | 219 | `needInt(Big)` yazdırmayı da deneyin. 220 | 221 | (Bir `int` en fazla 64 bit genişliğinde bir tamsayı depolar. Genişlik bazen bunun da altındadır.) 222 | 223 | .play basics/numeric-constants.go 224 | 225 | * Tebrikler! 226 | 227 | Bu dersin sonuna geldiniz! 228 | 229 | Daha neler öğreneceğinizi görmek için [[/list][bölüm listesine]] geri dönün ya da [[javascript:click('.next-page')][bir sonraki derse]] geçin. 230 | -------------------------------------------------------------------------------- /content/basics/basic-types.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math/cmplx" 8 | ) 9 | 10 | var ( 11 | ToBe bool = false 12 | MaxInt uint64 = 1<<64 - 1 13 | z complex128 = cmplx.Sqrt(-5 + 12i) 14 | ) 15 | 16 | func main() { 17 | const f = "%T(%v)\n" 18 | fmt.Printf(f, ToBe, ToBe) 19 | fmt.Printf(f, MaxInt, MaxInt) 20 | fmt.Printf(f, z, z) 21 | } 22 | -------------------------------------------------------------------------------- /content/basics/constants.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | const Pi = 3.14 8 | 9 | func main() { 10 | const World = "世界" 11 | fmt.Println("Hello", World) 12 | fmt.Println("Happy", Pi, "Day") 13 | 14 | const Truth = true 15 | fmt.Println("Go rules?", Truth) 16 | } 17 | -------------------------------------------------------------------------------- /content/basics/exported-names.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func main() { 11 | fmt.Println(math.pi) 12 | } 13 | -------------------------------------------------------------------------------- /content/basics/functions-continued.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func add(x, y int) int { 8 | return x + y 9 | } 10 | 11 | func main() { 12 | fmt.Println(add(42, 13)) 13 | } 14 | -------------------------------------------------------------------------------- /content/basics/functions.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func add(x int, y int) int { 8 | return x + y 9 | } 10 | 11 | func main() { 12 | fmt.Println(add(42, 13)) 13 | } 14 | -------------------------------------------------------------------------------- /content/basics/imports.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func main() { 11 | fmt.Printf("Now you have %g problems.", math.Sqrt(7)) 12 | } 13 | -------------------------------------------------------------------------------- /content/basics/multiple-results.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func swap(x, y string) (string, string) { 8 | return y, x 9 | } 10 | 11 | func main() { 12 | a, b := swap("hello", "world") 13 | fmt.Println(a, b) 14 | } 15 | -------------------------------------------------------------------------------- /content/basics/named-results.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func split(sum int) (x, y int) { 8 | x = sum * 4 / 9 9 | y = sum - x 10 | return 11 | } 12 | 13 | func main() { 14 | fmt.Println(split(17)) 15 | } 16 | -------------------------------------------------------------------------------- /content/basics/numeric-constants.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | const ( 8 | // Create a huge number by shifting a 1 bit left 100 places. 9 | // In other words, the binary number that is 1 followed by 100 zeroes. 10 | Big = 1 << 100 11 | // Shift it right again 99 places, so we end up with 1<<1, or 2. 12 | Small = Big >> 99 13 | ) 14 | 15 | func needInt(x int) int { return x*10 + 1 } 16 | func needFloat(x float64) float64 { 17 | return x * 0.1 18 | } 19 | 20 | func main() { 21 | fmt.Println(needInt(Small)) 22 | fmt.Println(needFloat(Small)) 23 | fmt.Println(needFloat(Big)) 24 | } 25 | -------------------------------------------------------------------------------- /content/basics/packages.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math/rand" 8 | ) 9 | 10 | func main() { 11 | fmt.Println("My favorite number is", rand.Intn(10)) 12 | } 13 | -------------------------------------------------------------------------------- /content/basics/short-variable-declarations.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var i, j int = 1, 2 9 | k := 3 10 | c, python, java := true, false, "no!" 11 | 12 | fmt.Println(i, j, k, c, python, java) 13 | } 14 | -------------------------------------------------------------------------------- /content/basics/type-conversions.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func main() { 11 | var x, y int = 3, 4 12 | var f float64 = math.Sqrt(float64(x*x + y*y)) 13 | var z uint = uint(f) 14 | fmt.Println(x, y, z) 15 | } 16 | -------------------------------------------------------------------------------- /content/basics/type-inference.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | v := 42 // change me! 9 | fmt.Printf("v is of type %T\n", v) 10 | } 11 | -------------------------------------------------------------------------------- /content/basics/variables-with-initializers.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | var i, j int = 1, 2 8 | 9 | func main() { 10 | var c, python, java = true, false, "no!" 11 | fmt.Println(i, j, c, python, java) 12 | } 13 | -------------------------------------------------------------------------------- /content/basics/variables.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | var c, python, java bool 8 | 9 | func main() { 10 | var i int 11 | fmt.Println(i, c, python, java) 12 | } 13 | -------------------------------------------------------------------------------- /content/basics/zero.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var i int 9 | var f float64 10 | var b bool 11 | var s string 12 | fmt.Printf("%v %v %v %q\n", i, f, b, s) 13 | } 14 | -------------------------------------------------------------------------------- /content/concurrency.article: -------------------------------------------------------------------------------- 1 | Eşzamanlılık 2 | Go, eşzamanlılık özelliklerini dilin temel bir parçası olarak sunar. Bu bölüm, dilin sunduğu eşzamanlılık özelliklerini ve bunların nasıl kullanılacağını örnekler ile açıklar. 3 | 4 | Go Yazarları Sunar 5 | https://golang.org 6 | 7 | * Goroutine 8 | 9 | Bir _goroutine_ Go tarafından çalışma zamanında yönetilen hafif bir iş parçacığıdır ("lightweight thread"). 10 | 11 | go f(x, y, z) 12 | 13 | çağrısı 14 | 15 | f(x, y, z) 16 | 17 | fonksiyonunu çalıştıran yeni bir goroutine başlatır. 18 | 19 | `f`, `x`, `y` ve `z` ifadelerinin değerlendirilmesi mevcut "goroutine"de, `f` fonksiyonunun çalıştırılması ise yeni bir "goroutine"de gerçekleşir. 20 | 21 | Gorutinleri aynı adres uzayında çalışır, bu yüzden paylaşılmış bellek erişimi mutlaka eşzamanlanmalıdır. [[https://golang.org/pkg/sync/][`sync`]] paketi 22 | yararlı bazı eşzamanlama ilkelleri sağlar; bununla birlikte Go'da bulunan diğer eşzamanlama ilkelleri sayesinde buna çok ihtiyaç duymayacaksınız. (Bir sonraki slayta bakın.) 23 | 24 | .play concurrency/goroutines.go 25 | 26 | * Kanallar 27 | 28 | Kanallar ("channels"), `<-` kanal operatörü vasıtası ile değer gönderip alabildiğiniz bir veri hattıdır. 29 | 30 | ch <- v // v'yi ch kanalına yolla. 31 | v := <-ch // ch'den al ve 32 | // değeri v'ye ata. 33 | 34 | (Veri akışı ok yönünde gerçekleşir.) 35 | 36 | Tıpkı eşlemler ve dilimler gibi kanallar da kullanılmadan önce oluşturulmalıdır: 37 | 38 | ch := make(chan int) 39 | 40 | Varsayılan olarak, veri gönderimleri ve alımları diğer taraf hazır olana kadar bloklanır. Bu, "goroutine"lerin açık kilitler ("explicit locks") veya koşul değişkenleri ("conditional variables") kullanmadan eşzamanlanmasını sağlar. 41 | 42 | Örnek kod, dilimdeki sayıların toplamını hesap yükünü iki gorutinine paylaştırarak hesaplar. 43 | Her iki gorutin de işlerini tamamladığında nihai sonuç hesaplanır. 44 | 45 | .play concurrency/channels.go 46 | 47 | * Tamponlanmış Kanallar 48 | 49 | Kanallar _tamponlanabilir_. Tamponlanmış bir kanalı ilklendirmek için `make` fonksiyonunun ikinci parametresine tampon ("buffer") uzunluğunu girin: 50 | 51 | ch := make(chan int, 100) 52 | 53 | Tamponlanmış bir kanala veri gönderimleri, sadece tampon tamamen dolu olduğunda durur. Tamponlanmış bir kanaldan veri alımları ise tampon tamamen boş olduğunda durur. 54 | 55 | Örneğin tamponu gereğinden fazla dolacak şekilde düzenleyip, ne olduğunu gözlemleyin. 56 | 57 | .play concurrency/buffered-channels.go 58 | 59 | * Range ve Close 60 | 61 | Gönderici bir kanaldan daha fazla değer gönderilmeyeceğini belirtmek adına `close` yerleşik fonksiyonu ile bu kanalı kapatabilir. Alıcılar, alıcı ifadeye ikinci bir parametre ataması yaparak kanalın kapalı olup olmadığını öğrenebilir: 62 | 63 | v, ok := <-ch 64 | 65 | Eğer alınacak başka değer kalmamış ve kanal kapatılmışsa `ok` değişkeni `false` değerini alacaktır. 66 | 67 | `for`i`:=`range`c` döngüsü kanal kapanana kadar kanaldan tekrar tekrar değer alır. 68 | 69 | *Not:* Yalnızca gönderen kanalı kapatmalıdır, alıcı asla kapatmamalıdır. Kapalı kanala bir şeyler göndermek "paniğe" yol açacaktır. 70 | 71 | *Başka*bir*not*: Kanallar dosyalar gibi değildir; kapatmanız genellikle gerekmez. Kapatma işlemi yalnızca alıcıya daha başka değer gelmeyeceğini bildirmek maksadıyla yapılır, tıpkı bir `range` döngüsünü sonlandırmak gibi. 72 | 73 | .play concurrency/range-and-close.go 74 | 75 | * Select 76 | 77 | `select` deyimi bir "goroutine"nin birden fazla iletişim işleminde beklemesine izin verir. 78 | 79 | Bir `select`, `case` yollarından biri çalışabilir hale gelinceye dek bloke eder. Eğer birden fazla çalıştırılabilir `case` varsa aralarından rastgele birini seçer. 80 | 81 | .play concurrency/select.go 82 | 83 | * Varsayılan Select 84 | 85 | Eğer hazırda başka `case` yoksa `select` içerisindeki `default` çalıştırılır. 86 | 87 | Bloklanmadan veri alma ya da gönderme yapmak için `default` kullanın: 88 | 89 | select { 90 | case i := <-c: 91 | // i'yi kulllan 92 | default: 93 | // c'den almak bloklamalıydı 94 | } 95 | 96 | .play concurrency/default-selection.go 97 | 98 | * Alıştırma: Eşdeğer İkili Ağaçlar 99 | 100 | Aynı sıralı değerlerin tutulduğu yapraklara sahip çok sayıda farklı ikili ağaçlar olabilir. Örneğin burada 1, 1, 2, 3, 5, 8, 13 sıralı değerlerini tutan 101 | iki adet ikili ağaç var: 102 | 103 | .image /content/img/tree.png 104 | 105 | Çoğu dilde, iki adet ikili ağacın verileri aynı sırada tutup tutmadığını kontrol eden fonksiyonu gerçeklemek bir hayli karışıktır. Basit bir çözüm sunabilmek adına Go'nun eşzamanlılığını ve kanallarını kullanacağız. 106 | 107 | Bu örnek aşağıdaki türü tanımlayan `tree` paketini kullanır: 108 | 109 | type Tree struct { 110 | Left *Tree 111 | Value int 112 | Right *Tree 113 | } 114 | 115 | Açıklamaya [[javascript:click('.next-page')][sonraki sayfada]] devam edin. 116 | 117 | * Alıştırma: Eşdeğer İkili Ağaçlar 118 | 119 | *1.* `Walk` fonksiyonunu gerçekleyin. 120 | 121 | *2.* `Walk` fonksiyonunu test edin. 122 | 123 | `tree.New(k)` fonksiyonu `k`, `2k`, `3k`, ..., `10k` değerlerini tutarak rastgele yapılandırılmış bir ikili ağacı inşa eder. 124 | 125 | `ch` adında yeni bir kanal oluşturun ve `Walker` fonksiyonunu bu kanalda başlatın: 126 | 127 | go Walk(tree.New(1), ch) 128 | 129 | Daha sonra kanaldan 10 değer okuyun ve bunları yazdırın. Değerler 1, 2, 3, ..., 10 olmalı. 130 | 131 | *3.* `t1` ve `t2` ağaçlarının aynı değerleri saklayıp saklamadığını belirleyebilmek adına `Same` fonksiyonunu `Walk` kullanarak gerçekleyin. 132 | 133 | *4.* `Same` fonksiyonunu test edin. 134 | 135 | `Same(tree.New(1),`tree.New(1))` true ve `Same(tree.New(1),`tree.New(2))` false döndürmelidir. 136 | 137 | `Tree` dokümanlarına [[https://godoc.org/golang.org/x/tour/tree#Tree][şuradan]] erişebilirsiniz. 138 | 139 | .play concurrency/exercise-equivalent-binary-trees.go 140 | 141 | * sync.Mutex 142 | 143 | Kanalların gorutinler arasındaki haberleşmeyi harika şekilde nasıl sağladığını görmüştük. 144 | 145 | Peki ya haberleşmeye ihtiyacımız yoksa? Ya tek istediğimiz bir değişkene, çakışmalardan sakınmak için, aynı anda sadece bir gorutinin erişmesini sağlamak ise? 146 | 147 | Bu mekanizmaya _karşılıklı dışlama_ ("mutual exclusion") denilmekte ve mekanizmayı sağlayan veri türüne geleneksel olarak _mutex_ adı verilmektedir. 148 | 149 | Standart Go kitaplığında karşılıklı dışlama [[https://golang.org/pkg/sync/#Mutex][`sync.Mutex`]] veri türü ve ona ait iki metodla sağlanır: 150 | 151 | - `Lock` 152 | - `Unlock` 153 | 154 | Karşılıklı dışlamayla çalıştırılacak bir kod öbeğini, `Inc` metodunda görüldüğü gibi, kodu `Lock` ve `Unlock` çağrılarıyla çevreleyerek tanımlayabiliriz. 155 | 156 | Mutex kilidinin kaldırıldığından emin olmak için, `Value` metodunda görüldüğü gibi, `defer` yerleşik metodunu da kullanabiliriz. 157 | 158 | .play concurrency/mutex-counter.go 159 | 160 | * Alıştırma: Web Crawler 161 | 162 | Bu uygulamada Go'nun eşzamanlılık yeteneklerini kullanarak bir "web crawler" uygulamasını paralelleştirmeyi öğreneceksiniz. 163 | 164 | `Crawl` fonksiyonunu, URL'leri paralel olarak çekecek biçimde (aynı URL iki defa çekilmeyecek) düzenleyin. 165 | 166 | _İpucu_: çekilen URL'leri bir eşlemde önbellekleyebiliriz, fakat salt bir eşlem eşzamanlı kullanımda güvenli değildir! 167 | 168 | .play concurrency/exercise-web-crawler.go 169 | 170 | * Bundan sonrası... 171 | 172 | #appengine: İşe 173 | #appengine: [[https://golang.org/doc/install/][Go yükleyerek]] başlayabilirsiniz. 174 | 175 | #appengine: Go kurulumunuzu başarılı ile gerçekleştirdikten sonra,kaynaklar, bilgilendirici makaleler, videolar ve daha fazlasını bulabileceğiniz [[http://golang.org/doc/][Go Dokümantasyonu]] 176 | #appengine: yola koyulmanız başlamanız için gerekli temel bilgiyi sunacaktır. 177 | 178 | Go dilinin kurallarına uygun kod yazmaya başlamak için [[https://www.youtube.com/watch?v=XCsL89YtqCs][şu]] videoyu izleyebilir veya [[https://golang.org/doc/code.html][How to Write Go Code]] (Go Kodu Yazma) makalesini okuyabilirsiniz. 179 | 180 | Standart kütüphane kullanımına dair yardıma ihtiyacınız olursa, [[https://golang.org/pkg/][ilgili paket referansına]] göz atınız. Dilin genel kullanımı ile ilgili bilgi edinmek isterseniz akıcı ve anlaşılır bir dille yazılmış [[https://golang.org/ref/spec][Language Spec]] ten (Dil Belirtimi) faydalanın. 181 | 182 | Go’nun eşzamanlılık modeli üzerine daha detaylı bilgi edinmek için [[https://www.youtube.com/watch?v=f6kdp27TYZs][Go Eşzamanlılık Desenleri]] ([[https://talks.golang.org/2012/concurrency.slide][sunum]]) [[https://www.youtube.com/watch?v=QDDwwePbDtw][İleri Go Eşzamanlılık Desenleri]] ([[https://talks.golang.org/2013/advconc.slide][sunum]]) videolarını izleyiniz ve [[https://golang.org/doc/codewalk/sharemem/][Haberleşerek Hafızayı Paylaşma]] dokümanını okuyun. 183 | 184 | Web uygulamaları yazmaya başlamak için, [[http://vimeo.com/53221558][Basit Bir Programlama Ortamı]] ([[https://talks.golang.org/2012/simple.slide][sunum]]) videosunu izleyiniz ve [[https://golang.org/doc/articles/wiki/][Web Uygulamaları Yazma]] rehberini okuyun. 185 | 186 | [[https://golang.org/doc/codewalk/functions/][Go'da Birinci Sınıf Fonksiyonlar]], Go'daki fonksiyon türleri üzerine farklı bir bakış açısı sunacaktır. 187 | 188 | [[https://blog.golang.org/][Go Blog]] da çok sayıda bilgilendirici makale bulabilirsiniz. 189 | 190 | Daha fazlası için [[https://golang.org][golang.org]] adresini ziyaret ediniz. 191 | 192 | * Çeviri hakkında 193 | 194 | Go Turu çevirisi [[http://golang.org.tr][Go Programlama Dili Türkiye Topluluğu]] üyeleri tarafından yapılmıştır. 195 | -------------------------------------------------------------------------------- /content/concurrency/buffered-channels.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | ch := make(chan int, 2) 9 | ch <- 1 10 | ch <- 2 11 | fmt.Println(<-ch) 12 | fmt.Println(<-ch) 13 | } 14 | -------------------------------------------------------------------------------- /content/concurrency/channels.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func sum(s []int, c chan int) { 8 | sum := 0 9 | for _, v := range s { 10 | sum += v 11 | } 12 | c <- sum // send sum to c 13 | } 14 | 15 | func main() { 16 | s := []int{7, 2, 8, -9, 4, 0} 17 | 18 | c := make(chan int) 19 | go sum(s[:len(s)/2], c) 20 | go sum(s[len(s)/2:], c) 21 | x, y := <-c, <-c // receive from c 22 | 23 | fmt.Println(x, y, x+y) 24 | } 25 | -------------------------------------------------------------------------------- /content/concurrency/default-selection.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | tick := time.Tick(100 * time.Millisecond) 12 | boom := time.After(500 * time.Millisecond) 13 | for { 14 | select { 15 | case <-tick: 16 | fmt.Println("tick.") 17 | case <-boom: 18 | fmt.Println("BOOM!") 19 | return 20 | default: 21 | fmt.Println(" .") 22 | time.Sleep(50 * time.Millisecond) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /content/concurrency/exercise-equivalent-binary-trees.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import "golang.org/x/tour/tree" 6 | 7 | // Walk walks the tree t sending all values 8 | // from the tree to the channel ch. 9 | func Walk(t *tree.Tree, ch chan int) 10 | 11 | // Same determines whether the trees 12 | // t1 and t2 contain the same values. 13 | func Same(t1, t2 *tree.Tree) bool 14 | 15 | func main() { 16 | } 17 | -------------------------------------------------------------------------------- /content/concurrency/exercise-web-crawler.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | type Fetcher interface { 10 | // Fetch returns the body of URL and 11 | // a slice of URLs found on that page. 12 | Fetch(url string) (body string, urls []string, err error) 13 | } 14 | 15 | // Crawl uses fetcher to recursively crawl 16 | // pages starting with url, to a maximum of depth. 17 | func Crawl(url string, depth int, fetcher Fetcher) { 18 | // TODO: Fetch URLs in parallel. 19 | // TODO: Don't fetch the same URL twice. 20 | // This implementation doesn't do either: 21 | if depth <= 0 { 22 | return 23 | } 24 | body, urls, err := fetcher.Fetch(url) 25 | if err != nil { 26 | fmt.Println(err) 27 | return 28 | } 29 | fmt.Printf("found: %s %q\n", url, body) 30 | for _, u := range urls { 31 | Crawl(u, depth-1, fetcher) 32 | } 33 | return 34 | } 35 | 36 | func main() { 37 | Crawl("http://golang.org/", 4, fetcher) 38 | } 39 | 40 | // fakeFetcher is Fetcher that returns canned results. 41 | type fakeFetcher map[string]*fakeResult 42 | 43 | type fakeResult struct { 44 | body string 45 | urls []string 46 | } 47 | 48 | func (f fakeFetcher) Fetch(url string) (string, []string, error) { 49 | if res, ok := f[url]; ok { 50 | return res.body, res.urls, nil 51 | } 52 | return "", nil, fmt.Errorf("not found: %s", url) 53 | } 54 | 55 | // fetcher is a populated fakeFetcher. 56 | var fetcher = fakeFetcher{ 57 | "http://golang.org/": &fakeResult{ 58 | "The Go Programming Language", 59 | []string{ 60 | "http://golang.org/pkg/", 61 | "http://golang.org/cmd/", 62 | }, 63 | }, 64 | "http://golang.org/pkg/": &fakeResult{ 65 | "Packages", 66 | []string{ 67 | "http://golang.org/", 68 | "http://golang.org/cmd/", 69 | "http://golang.org/pkg/fmt/", 70 | "http://golang.org/pkg/os/", 71 | }, 72 | }, 73 | "http://golang.org/pkg/fmt/": &fakeResult{ 74 | "Package fmt", 75 | []string{ 76 | "http://golang.org/", 77 | "http://golang.org/pkg/", 78 | }, 79 | }, 80 | "http://golang.org/pkg/os/": &fakeResult{ 81 | "Package os", 82 | []string{ 83 | "http://golang.org/", 84 | "http://golang.org/pkg/", 85 | }, 86 | }, 87 | } 88 | -------------------------------------------------------------------------------- /content/concurrency/goroutines.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func say(s string) { 11 | for i := 0; i < 5; i++ { 12 | time.Sleep(100 * time.Millisecond) 13 | fmt.Println(s) 14 | } 15 | } 16 | 17 | func main() { 18 | go say("world") 19 | say("hello") 20 | } 21 | -------------------------------------------------------------------------------- /content/concurrency/mutex-counter.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "sync" 8 | "time" 9 | ) 10 | 11 | // SafeCounter is safe to use concurrently. 12 | type SafeCounter struct { 13 | v map[string]int 14 | mux sync.Mutex 15 | } 16 | 17 | // Inc increments the counter for the given key. 18 | func (c *SafeCounter) Inc(key string) { 19 | c.mux.Lock() 20 | // Lock so only one goroutine at a time can access the map c.v. 21 | c.v[key]++ 22 | c.mux.Unlock() 23 | } 24 | 25 | // Value returns the current value of the counter for the given key. 26 | func (c *SafeCounter) Value(key string) int { 27 | c.mux.Lock() 28 | // Lock so only one goroutine at a time can access the map c.v. 29 | defer c.mux.Unlock() 30 | return c.v[key] 31 | } 32 | 33 | func main() { 34 | c := SafeCounter{v: make(map[string]int)} 35 | for i := 0; i < 1000; i++ { 36 | go c.Inc("somekey") 37 | } 38 | 39 | time.Sleep(time.Second) 40 | fmt.Println(c.Value("somekey")) 41 | } 42 | -------------------------------------------------------------------------------- /content/concurrency/range-and-close.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | func fibonacci(n int, c chan int) { 10 | x, y := 0, 1 11 | for i := 0; i < n; i++ { 12 | c <- x 13 | x, y = y, x+y 14 | } 15 | close(c) 16 | } 17 | 18 | func main() { 19 | c := make(chan int, 10) 20 | go fibonacci(cap(c), c) 21 | for i := range c { 22 | fmt.Println(i) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /content/concurrency/select.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func fibonacci(c, quit chan int) { 8 | x, y := 0, 1 9 | for { 10 | select { 11 | case c <- x: 12 | x, y = y, x+y 13 | case <-quit: 14 | fmt.Println("quit") 15 | return 16 | } 17 | } 18 | } 19 | 20 | func main() { 21 | c := make(chan int) 22 | quit := make(chan int) 23 | go func() { 24 | for i := 0; i < 10; i++ { 25 | fmt.Println(<-c) 26 | } 27 | quit <- 0 28 | }() 29 | fibonacci(c, quit) 30 | } 31 | -------------------------------------------------------------------------------- /content/content_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package content 6 | 7 | import ( 8 | "bytes" 9 | "errors" 10 | "fmt" 11 | "io/ioutil" 12 | "os" 13 | "os/exec" 14 | "path/filepath" 15 | "strings" 16 | "testing" 17 | ) 18 | 19 | // Test that all the .go files inside the content file build 20 | // and execute (without checking for output correctness). 21 | // Files that contain the string "// +build no-build" are not built. 22 | // Files that contain the string "// +build no-run" are not executed. 23 | func TestContent(t *testing.T) { 24 | scratch, err := ioutil.TempDir("", "tour-content-test") 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | defer os.RemoveAll(scratch) 29 | 30 | err = filepath.Walk(".", func(path string, fi os.FileInfo, err error) error { 31 | if filepath.Ext(path) != ".go" { 32 | return nil 33 | } 34 | if filepath.Base(path) == "content_test.go" { 35 | return nil 36 | } 37 | if err := testSnippet(t, path, scratch); err != nil { 38 | t.Errorf("%v: %v", path, err) 39 | } 40 | return nil 41 | }) 42 | if err != nil { 43 | t.Error(err) 44 | } 45 | } 46 | 47 | func testSnippet(t *testing.T, path, scratch string) error { 48 | b, err := ioutil.ReadFile(path) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | build := string(bytes.SplitN(b, []byte{'\n'}, 2)[0]) 54 | if !strings.HasPrefix(build, "// +build ") { 55 | return errors.New("first line is not a +build comment") 56 | } 57 | if !strings.Contains(build, "OMIT") { 58 | return errors.New(`+build comment does not contain "OMIT"`) 59 | } 60 | 61 | if strings.Contains(build, "no-build") { 62 | return nil 63 | } 64 | bin := filepath.Join(scratch, filepath.Base(path)+".exe") 65 | out, err := exec.Command("go", "build", "-o", bin, path).CombinedOutput() 66 | if err != nil { 67 | return fmt.Errorf("build error: %v\noutput:\n%s", err, out) 68 | } 69 | defer os.Remove(bin) 70 | 71 | if strings.Contains(build, "no-run") { 72 | return nil 73 | } 74 | out, err = exec.Command(bin).CombinedOutput() 75 | if err != nil { 76 | return fmt.Errorf("%v\nOutput:\n%s", err, out) 77 | } 78 | return nil 79 | } 80 | -------------------------------------------------------------------------------- /content/flowcontrol.article: -------------------------------------------------------------------------------- 1 | Akış kontrol deyimleri: for, if, else, switch ve defer 2 | Kodunuzun akışını koşullar, döngüler, "switch"ler ve "defer"ler ile nasıl kontrol edeceğinizi öğrenin. 3 | 4 | Go Yazarları Sunar 5 | https://golang.org 6 | 7 | * For 8 | 9 | Go dilinde döngü yapısı olarak sadece `for` mevcuttur. 10 | 11 | `for` döngüsü noktalı virgüller ayrılmış üç kısımdan oluşur: 12 | 13 | - ilklendirme deyimi: ilk döngüden önce çalıştırılır 14 | - koşul ifadesi: her döngüden önce değerlendirilir 15 | - sonlandırma deyimi: her döngünün sonunda çalıştırılır 16 | 17 | İlklendirme deyimi sıklıkla kısa bir değişken bildirimidir ve bildirilen değişkenler sadece `for` deyiminin kapsamında geçerlidir. 18 | 19 | Döngü koşulu `false` olarak değerlendirildiğinde döngüye girilmeden deyim sonlanır. 20 | 21 | _Not_: C, Java ve Javascript gibi dillerden farklı olarak `for` deyiminin üç kısımlı başlangıcı etrafında `(`)` parantezleri bulunmaz, fakat `{`}` parantezleri daima gereklidir. 22 | 23 | .play flowcontrol/for.go 24 | 25 | * For devam 26 | 27 | İlklendirme (birinci) ve sonlandırma (üçüncü) deyimlerini boş bırakabilirsiniz. 28 | 29 | .play flowcontrol/for-continued.go 30 | 31 | * For, Go'nun "while"ıdır 32 | 33 | Bu aşamada `for` deyimindeki noktalı virgülleri de bir köşeye atabilirsiniz: C'deki `while` deyiminin Go'da karşılığı `for` deyimidir. 34 | 35 | .play flowcontrol/for-is-gos-while.go 36 | 37 | * Sonsuza dek 38 | 39 | Eğer döngü koşulunu belirtmezseniz, sonsuz döngü oluşacaktır. 40 | 41 | Sonsuzluğu küçücük bir alana sığdırdık. 42 | 43 | .play flowcontrol/forever.go 44 | 45 | * If 46 | 47 | Go'da `if` deyimleri görünüm olarak `for` döngüleri gibidir; koşul ifadesinde `(`)` (parantezler) kullanılmaz, ama `{`}` (süslü parantez) kullanılması zorunludur. 48 | 49 | .play flowcontrol/if.go 50 | 51 | * Kısa bir deyim ile if kullanımı 52 | 53 | `for` deyiminde olduğu gibi, `if` deyimi de koşuldan önce çalıştırılacak kısa bir deyim ile başlayabilir. 54 | 55 | Bu kısa deyimde belirtilen değişkenler, `if` koşulunun kapsamı içinde geçerlidir. 56 | 57 | (En sondaki return deyiminde `lim` yerine `v` kullanmayı deneyin.) 58 | 59 | .play flowcontrol/if-with-a-short-statement.go 60 | 61 | * If ve else 62 | 63 | `if` deyiminin kapsamında geçerli olan kısa atama ile atanan değişkenler, `else` blokları içinde de geçerlidir. 64 | 65 | (Her iki `pow` çağrısı da gerçekleşir ve `main`de `fmt.Println` çağrısı başlamadan tamamlanır.) 66 | 67 | .play flowcontrol/if-and-else.go 68 | 69 | * Alıştırma: Döngüler ve Fonksiyonlar 70 | 71 | Karekök alma fonksiyonunu Newton metoduyla gerçekleyin. 72 | 73 | Newton metodunda; bir _z_ başlangıç noktası seçilir ve 74 | 75 | .image /content/img/newton.png 76 | 77 | formülünü tekrarlayarak `Sqrt(x)` ("karekök x") değerine yaklaşılır. 78 | 79 | Başlangıç olarak bu hesaplamayı 10 defa tekrar edin ve (1, 2, 3, ...) çeşitli değerlerle cevaba ne kadar yaklaştığınızı görün. 80 | 81 | Daha sonra döngü koşulunu, sonuç değeri değişmeyi bıraktığında (ya da çok küçük bir fark ile değiştiğinde) döngünün durmasını sağlayacak şekilde düzenleyin. Döngünün daha fazla veya daha az çalışıp çalışmadığına bakın. [[https://golang.org/pkg/math/#Sqrt][Math.sqrt]] fonksiyonunun verdiği sonuca ne kadar yakın bir cevap elde ettiniz? 82 | 83 | İpucu: bir kayan noktalı sayı değeri ("floating point value") bildirmek ve ilklendirmek için ya kayan noktalı sayı bildirimi sözdizimini kullanın ya da dönüştürme işlemi uygulayın: 84 | 85 | z := float64(1) 86 | z := 1.0 87 | 88 | .play flowcontrol/exercise-loops-and-functions.go 89 | 90 | * Switch 91 | 92 | Muhtemelen `switch` (anahtarlama) deyiminin neye benzediğini biliyorsunuzdur. 93 | 94 | `fallthrough` deyimi ile sonlanana kadar, `case` gövdesi otomatik olarak sonlanacaktır. 95 | 96 | .play flowcontrol/switch.go 97 | 98 | * Switch değerlendirme sırası 99 | 100 | "Switch" deyiminde "case"ler yukarıdan aşağıya değerlendirir ve "case"lerden biri doğrulandığında değerlendirme sonlanır. 101 | 102 | (Örneğin, 103 | 104 | switch i { 105 | case 0: 106 | case f(): 107 | } 108 | 109 | eğer `i==0` ise `f` fonksiyonu çağırılmaz.) 110 | 111 | #appengine: *Not:* Go Playground'ta zaman her daim 2009-11-10 23:00:00 UTC'den başlar, 112 | #appengine: bu değerin önemi okuyucu için bir alıştırma niteliğinde olmasıdır. 113 | 114 | .play flowcontrol/switch-evaluation-order.go 115 | 116 | * Koşulsuz Switch 117 | 118 | Koşul belirtilmemiş bir `switch` deyimi, `switch`true` deyimiyle eşdeğerdir. 119 | 120 | Bu yapı uzun "if-then-else" zincirleri yerine kullanılabilecek temiz bir yöntemdir. 121 | 122 | .play flowcontrol/switch-with-no-condition.go 123 | 124 | * Defer 125 | 126 | defer deyimi, kendisini çevreleyen fonksiyon dönene kadar fonksiyonun çalışmasını erteler. 127 | 128 | Ertelenmiş fonksiyon çağrısının argümanları anında değerlendirilir, fakat fonksiyon çağrısı kendisini çevreleyen fonksiyon dönmeden işleme sokulmaz. 129 | 130 | .play flowcontrol/defer.go 131 | 132 | * Defer yığını 133 | 134 | Ertelenmiş fonksiyon çağrıları yığının tepesine yerleştirilir. Bir fonksiyon döndüğü zaman, onun çevrelediği ertelenmiş fonksiyonlar son-giren-ilk-çıkar (LIFO) sırasına göre çağrılır. 135 | 136 | defer deyimleri hakkında daha fazlasını öğrenmek için şu [[https://blog.golang.org/defer-panic-and-recover][blog yazısını]] okuyun. 137 | 138 | .play flowcontrol/defer-multi.go 139 | 140 | * Tebrikler! 141 | 142 | Bu dersin sonuna geldiniz! 143 | 144 | Daha neler öğreneceğinizi görmek için [[/list][bölüm listesine]] geri dönün ya da [[javascript:click('.next-page')][bir sonraki derse]] geçin. 145 | -------------------------------------------------------------------------------- /content/flowcontrol/defer-multi.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | fmt.Println("counting") 9 | 10 | for i := 0; i < 10; i++ { 11 | defer fmt.Println(i) 12 | } 13 | 14 | fmt.Println("done") 15 | } 16 | -------------------------------------------------------------------------------- /content/flowcontrol/defer.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | defer fmt.Println("world") 9 | 10 | fmt.Println("hello") 11 | } 12 | -------------------------------------------------------------------------------- /content/flowcontrol/exercise-loops-and-functions.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | func Sqrt(x float64) float64 { 10 | } 11 | 12 | func main() { 13 | fmt.Println(Sqrt(2)) 14 | } 15 | -------------------------------------------------------------------------------- /content/flowcontrol/for-continued.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | sum := 1 9 | for ; sum < 1000; { 10 | sum += sum 11 | } 12 | fmt.Println(sum) 13 | } 14 | -------------------------------------------------------------------------------- /content/flowcontrol/for-is-gos-while.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | sum := 1 9 | for sum < 1000 { 10 | sum += sum 11 | } 12 | fmt.Println(sum) 13 | } 14 | -------------------------------------------------------------------------------- /content/flowcontrol/for.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | sum := 0 9 | for i := 0; i < 10; i++ { 10 | sum += i 11 | } 12 | fmt.Println(sum) 13 | } 14 | -------------------------------------------------------------------------------- /content/flowcontrol/forever.go: -------------------------------------------------------------------------------- 1 | // +build no-run OMIT 2 | 3 | package main 4 | 5 | func main() { 6 | for { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /content/flowcontrol/if-and-else.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func pow(x, n, lim float64) float64 { 11 | if v := math.Pow(x, n); v < lim { 12 | return v 13 | } else { 14 | fmt.Printf("%g >= %g\n", v, lim) 15 | } 16 | // can't use v here, though 17 | return lim 18 | } 19 | 20 | func main() { 21 | fmt.Println( 22 | pow(3, 2, 10), 23 | pow(3, 3, 20), 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /content/flowcontrol/if-with-a-short-statement.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func pow(x, n, lim float64) float64 { 11 | if v := math.Pow(x, n); v < lim { 12 | return v 13 | } 14 | return lim 15 | } 16 | 17 | func main() { 18 | fmt.Println( 19 | pow(3, 2, 10), 20 | pow(3, 3, 20), 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /content/flowcontrol/if.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func sqrt(x float64) string { 11 | if x < 0 { 12 | return sqrt(-x) + "i" 13 | } 14 | return fmt.Sprint(math.Sqrt(x)) 15 | } 16 | 17 | func main() { 18 | fmt.Println(sqrt(2), sqrt(-4)) 19 | } 20 | -------------------------------------------------------------------------------- /content/flowcontrol/switch-evaluation-order.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | fmt.Println("When's Saturday?") 12 | today := time.Now().Weekday() 13 | switch time.Saturday { 14 | case today + 0: 15 | fmt.Println("Today.") 16 | case today + 1: 17 | fmt.Println("Tomorrow.") 18 | case today + 2: 19 | fmt.Println("In two days.") 20 | default: 21 | fmt.Println("Too far away.") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /content/flowcontrol/switch-with-no-condition.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | t := time.Now() 12 | switch { 13 | case t.Hour() < 12: 14 | fmt.Println("Good morning!") 15 | case t.Hour() < 17: 16 | fmt.Println("Good afternoon.") 17 | default: 18 | fmt.Println("Good evening.") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /content/flowcontrol/switch.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "runtime" 8 | ) 9 | 10 | func main() { 11 | fmt.Print("Go runs on ") 12 | switch os := runtime.GOOS; os { 13 | case "darwin": 14 | fmt.Println("OS X.") 15 | case "linux": 16 | fmt.Println("Linux.") 17 | default: 18 | // freebsd, openbsd, 19 | // plan9, windows... 20 | fmt.Printf("%s.", os) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /content/img/newton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-tr/tour/ed657b3550a3f599ec17ec6e477f311e91cb5e77/content/img/newton.png -------------------------------------------------------------------------------- /content/img/tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-tr/tour/ed657b3550a3f599ec17ec6e477f311e91cb5e77/content/img/tree.png -------------------------------------------------------------------------------- /content/methods/empty-interface.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var i interface{} 9 | describe(i) 10 | 11 | i = 42 12 | describe(i) 13 | 14 | i = "hello" 15 | describe(i) 16 | } 17 | 18 | func describe(i interface{}) { 19 | fmt.Printf("(%v, %T)\n", i, i) 20 | } 21 | -------------------------------------------------------------------------------- /content/methods/errors.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | type MyError struct { 11 | When time.Time 12 | What string 13 | } 14 | 15 | func (e *MyError) Error() string { 16 | return fmt.Sprintf("at %v, %s", 17 | e.When, e.What) 18 | } 19 | 20 | func run() error { 21 | return &MyError{ 22 | time.Now(), 23 | "it didn't work", 24 | } 25 | } 26 | 27 | func main() { 28 | if err := run(); err != nil { 29 | fmt.Println(err) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /content/methods/exercise-errors.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | ) 8 | 9 | func Sqrt(x float64) (float64, error) { 10 | return 0, nil 11 | } 12 | 13 | func main() { 14 | fmt.Println(Sqrt(2)) 15 | fmt.Println(Sqrt(-2)) 16 | } 17 | -------------------------------------------------------------------------------- /content/methods/exercise-images.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import "golang.org/x/tour/pic" 6 | 7 | type Image struct{} 8 | 9 | func main() { 10 | m := Image{} 11 | pic.ShowImage(m) 12 | } 13 | -------------------------------------------------------------------------------- /content/methods/exercise-reader.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import "golang.org/x/tour/reader" 6 | 7 | type MyReader struct{} 8 | 9 | // TODO: Add a Read([]byte) (int, error) method to MyReader. 10 | 11 | func main() { 12 | reader.Validate(MyReader{}) 13 | } 14 | -------------------------------------------------------------------------------- /content/methods/exercise-rot-reader.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "io" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | type rot13Reader struct { 12 | r io.Reader 13 | } 14 | 15 | func main() { 16 | s := strings.NewReader("Lbh penpxrq gur pbqr!") 17 | r := rot13Reader{s} 18 | io.Copy(os.Stdout, &r) 19 | } 20 | -------------------------------------------------------------------------------- /content/methods/exercise-stringer.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type IPAddr [4]byte 8 | 9 | // TODO: Add a "String() string" method to IPAddr. 10 | 11 | func main() { 12 | hosts := map[string]IPAddr{ 13 | "loopback": {127, 0, 0, 1}, 14 | "googleDNS": {8, 8, 8, 8}, 15 | } 16 | for name, ip := range hosts { 17 | fmt.Printf("%v: %v\n", name, ip) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /content/methods/images.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "image" 8 | ) 9 | 10 | func main() { 11 | m := image.NewRGBA(image.Rect(0, 0, 100, 100)) 12 | fmt.Println(m.Bounds()) 13 | fmt.Println(m.At(0, 0).RGBA()) 14 | } 15 | -------------------------------------------------------------------------------- /content/methods/indirection-values.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Vertex struct { 11 | X, Y float64 12 | } 13 | 14 | func (v Vertex) Abs() float64 { 15 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 16 | } 17 | 18 | func AbsFunc(v Vertex) float64 { 19 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 20 | } 21 | 22 | func main() { 23 | v := Vertex{3, 4} 24 | fmt.Println(v.Abs()) 25 | fmt.Println(AbsFunc(v)) 26 | 27 | p := &Vertex{4, 3} 28 | fmt.Println(p.Abs()) 29 | fmt.Println(AbsFunc(*p)) 30 | } 31 | -------------------------------------------------------------------------------- /content/methods/indirection.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | X, Y float64 9 | } 10 | 11 | func (v *Vertex) Scale(f float64) { 12 | v.X = v.X * f 13 | v.Y = v.Y * f 14 | } 15 | 16 | func ScaleFunc(v *Vertex, f float64) { 17 | v.X = v.X * f 18 | v.Y = v.Y * f 19 | } 20 | 21 | func main() { 22 | v := Vertex{3, 4} 23 | v.Scale(2) 24 | ScaleFunc(&v, 10) 25 | 26 | p := &Vertex{4, 3} 27 | p.Scale(3) 28 | ScaleFunc(p, 8) 29 | 30 | fmt.Println(v, p) 31 | } 32 | -------------------------------------------------------------------------------- /content/methods/interface-values-with-nil.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type I interface { 8 | M() 9 | } 10 | 11 | type T struct { 12 | S string 13 | } 14 | 15 | func (t *T) M() { 16 | if t == nil { 17 | fmt.Println("") 18 | return 19 | } 20 | fmt.Println(t.S) 21 | } 22 | 23 | func main() { 24 | var i I 25 | 26 | var t *T 27 | i = t 28 | describe(i) 29 | i.M() 30 | 31 | i = &T{"hello"} 32 | describe(i) 33 | i.M() 34 | } 35 | 36 | func describe(i I) { 37 | fmt.Printf("(%v, %T)\n", i, i) 38 | } 39 | -------------------------------------------------------------------------------- /content/methods/interface-values.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type I interface { 11 | M() 12 | } 13 | 14 | type T struct { 15 | S string 16 | } 17 | 18 | func (t *T) M() { 19 | fmt.Println(t.S) 20 | } 21 | 22 | type F float64 23 | 24 | func (f F) M() { 25 | fmt.Println(f) 26 | } 27 | 28 | func main() { 29 | var i I 30 | 31 | i = &T{"Hello"} 32 | describe(i) 33 | i.M() 34 | 35 | i = F(math.Pi) 36 | describe(i) 37 | i.M() 38 | } 39 | 40 | func describe(i I) { 41 | fmt.Printf("(%v, %T)\n", i, i) 42 | } 43 | -------------------------------------------------------------------------------- /content/methods/interfaces-are-satisfied-implicitly.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type I interface { 8 | M() 9 | } 10 | 11 | type T struct { 12 | S string 13 | } 14 | 15 | // This method means type T implements the interface I, 16 | // but we don't need to explicitly declare that it does so. 17 | func (t T) M() { 18 | fmt.Println(t.S) 19 | } 20 | 21 | func main() { 22 | var i I = T{"hello"} 23 | i.M() 24 | } 25 | -------------------------------------------------------------------------------- /content/methods/interfaces.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Abser interface { 11 | Abs() float64 12 | } 13 | 14 | func main() { 15 | var a Abser 16 | f := MyFloat(-math.Sqrt2) 17 | v := Vertex{3, 4} 18 | 19 | a = f // a MyFloat implements Abser 20 | a = &v // a *Vertex implements Abser 21 | 22 | // In the following line, v is a Vertex (not *Vertex) 23 | // and does NOT implement Abser. 24 | a = v 25 | 26 | fmt.Println(a.Abs()) 27 | } 28 | 29 | type MyFloat float64 30 | 31 | func (f MyFloat) Abs() float64 { 32 | if f < 0 { 33 | return float64(-f) 34 | } 35 | return float64(f) 36 | } 37 | 38 | type Vertex struct { 39 | X, Y float64 40 | } 41 | 42 | func (v *Vertex) Abs() float64 { 43 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 44 | } 45 | -------------------------------------------------------------------------------- /content/methods/methods-continued.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type MyFloat float64 11 | 12 | func (f MyFloat) Abs() float64 { 13 | if f < 0 { 14 | return float64(-f) 15 | } 16 | return float64(f) 17 | } 18 | 19 | func main() { 20 | f := MyFloat(-math.Sqrt2) 21 | fmt.Println(f.Abs()) 22 | } 23 | -------------------------------------------------------------------------------- /content/methods/methods-funcs.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Vertex struct { 11 | X, Y float64 12 | } 13 | 14 | func Abs(v Vertex) float64 { 15 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 16 | } 17 | 18 | func main() { 19 | v := Vertex{3, 4} 20 | fmt.Println(Abs(v)) 21 | } 22 | -------------------------------------------------------------------------------- /content/methods/methods-pointers-explained.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Vertex struct { 11 | X, Y float64 12 | } 13 | 14 | func Abs(v Vertex) float64 { 15 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 16 | } 17 | 18 | func Scale(v *Vertex, f float64) { 19 | v.X = v.X * f 20 | v.Y = v.Y * f 21 | } 22 | 23 | func main() { 24 | v := Vertex{3, 4} 25 | Scale(&v, 10) 26 | fmt.Println(Abs(v)) 27 | } 28 | -------------------------------------------------------------------------------- /content/methods/methods-pointers.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Vertex struct { 11 | X, Y float64 12 | } 13 | 14 | func (v Vertex) Abs() float64 { 15 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 16 | } 17 | 18 | func (v *Vertex) Scale(f float64) { 19 | v.X = v.X * f 20 | v.Y = v.Y * f 21 | } 22 | 23 | func main() { 24 | v := Vertex{3, 4} 25 | v.Scale(10) 26 | fmt.Println(v.Abs()) 27 | } 28 | -------------------------------------------------------------------------------- /content/methods/methods-with-pointer-receivers.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Vertex struct { 11 | X, Y float64 12 | } 13 | 14 | func (v *Vertex) Scale(f float64) { 15 | v.X = v.X * f 16 | v.Y = v.Y * f 17 | } 18 | 19 | func (v *Vertex) Abs() float64 { 20 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 21 | } 22 | 23 | func main() { 24 | v := &Vertex{3, 4} 25 | fmt.Printf("Before scaling: %+v, Abs: %v\n", v, v.Abs()) 26 | v.Scale(5) 27 | fmt.Printf("After scaling: %+v, Abs: %v\n", v, v.Abs()) 28 | } 29 | -------------------------------------------------------------------------------- /content/methods/methods.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | type Vertex struct { 11 | X, Y float64 12 | } 13 | 14 | func (v Vertex) Abs() float64 { 15 | return math.Sqrt(v.X*v.X + v.Y*v.Y) 16 | } 17 | 18 | func main() { 19 | v := Vertex{3, 4} 20 | fmt.Println(v.Abs()) 21 | } 22 | -------------------------------------------------------------------------------- /content/methods/nil-interface-values.go: -------------------------------------------------------------------------------- 1 | // +build no-run OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type I interface { 8 | M() 9 | } 10 | 11 | func main() { 12 | var i I 13 | describe(i) 14 | i.M() 15 | } 16 | 17 | func describe(i I) { 18 | fmt.Printf("(%v, %T)\n", i, i) 19 | } 20 | -------------------------------------------------------------------------------- /content/methods/reader.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "io" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | r := strings.NewReader("Hello, Reader!") 13 | 14 | b := make([]byte, 8) 15 | for { 16 | n, err := r.Read(b) 17 | fmt.Printf("n = %v err = %v b = %v\n", n, err, b) 18 | fmt.Printf("b[:n] = %q\n", b[:n]) 19 | if err == io.EOF { 20 | break 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /content/methods/stringer.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Person struct { 8 | Name string 9 | Age int 10 | } 11 | 12 | func (p Person) String() string { 13 | return fmt.Sprintf("%v (%v years)", p.Name, p.Age) 14 | } 15 | 16 | func main() { 17 | a := Person{"Arthur Dent", 42} 18 | z := Person{"Zaphod Beeblebrox", 9001} 19 | fmt.Println(a, z) 20 | } 21 | -------------------------------------------------------------------------------- /content/methods/type-assertions.go: -------------------------------------------------------------------------------- 1 | // +build no-run OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var i interface{} = "hello" 9 | 10 | s := i.(string) 11 | fmt.Println(s) 12 | 13 | s, ok := i.(string) 14 | fmt.Println(s, ok) 15 | 16 | f, ok := i.(float64) 17 | fmt.Println(f, ok) 18 | 19 | f = i.(float64) // panic 20 | fmt.Println(f) 21 | } 22 | -------------------------------------------------------------------------------- /content/methods/type-switches.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func do(i interface{}) { 8 | switch v := i.(type) { 9 | case int: 10 | fmt.Printf("Twice %v is %v\n", v, v*2) 11 | case string: 12 | fmt.Printf("%q is %v bytes long\n", v, len(v)) 13 | default: 14 | fmt.Printf("I don't know about type %T!\n", v) 15 | } 16 | } 17 | 18 | func main() { 19 | do(21) 20 | do("hello") 21 | do(true) 22 | } 23 | -------------------------------------------------------------------------------- /content/moretypes.article: -------------------------------------------------------------------------------- 1 | Diğer türler: yapı ("struct"), dilim ("slice") ve eşlem ("map") 2 | Varolan türleri temel alarak tür tanımlamayı öğrenin: bu bölüm yapılar ("struct"), diziler ("array"), dilimler ("slice") ve eşlemleri ("map") kapsar. 3 | 4 | Go Yazarları Sunar 5 | https://golang.org 6 | 7 | * İşaretçiler 8 | 9 | Go dilinde işaretçiler ("pointer") mevcuttur. 10 | İşaretçi değişkenin bellekteki adresini tutar. 11 | 12 | `*T`, `T` değerini gösteren bir türdür. Sıfır değeri olarak `nil` kullanılır. 13 | 14 | var p *int 15 | 16 | `&` operatörü başına geldiği terimi gösteren bir gösterici oluşturur. 17 | 18 | i := 42 19 | p = &i 20 | 21 | `*` operatörü, göstericinin gösterdiği değişkenin değerini gösterir. 22 | 23 | fmt.Println(*p) // p göstericisi üzerinden i'nin değerini oku 24 | *p = 21 // p göstericisi üzerinden i'ye değer ata 25 | 26 | Buna dolaylı yoldan erişim denir. 27 | 28 | C dilinin aksine, Go dilinde gösterici aritmetiği desteklenmez. 29 | 30 | .play moretypes/pointers.go 31 | 32 | * Yapılar 33 | 34 | Struct ("yapı"), alanlardan oluşan bir veri topluluğudur. 35 | 36 | (`type` bildirimi yapı ("struct") oluşturmaya yarar.) 37 | 38 | .play moretypes/structs.go 39 | 40 | * Yapı Alanları 41 | 42 | Yapı alanlarına nokta kullanılarak erişilir. 43 | 44 | .play moretypes/struct-fields.go 45 | 46 | * Yapı Göstericileri 47 | 48 | Yapı alanlarına yapı göstericisi ile erişilebilir. 49 | 50 | Gösterici üzerinden yapılan dolaylama belirgindir. 51 | 52 | Elimizdeki `p` yapı işaretçisiyle, bir yapının `X` alanına erişmek için `(*p).X` yazabiliriz. 53 | Bununla birlikte bu gösterim kullanışsız olduğundan Dil bize bunun yerine doğrudan `p.X` yazma iznini de vermektedir. 54 | 55 | .play moretypes/struct-pointers.go 56 | 57 | * Yapı Değerleri 58 | 59 | Bir yapı değeri ("struct literal"), henüz bellek ayrılmış yeni bir yapı değerini, alanlarının değerlerini listeleyerek belirtir. 60 | 61 | `Name:` sözdizimini kullanarak yalnızca alt alanları listeleyebilirsiniz (alan sırası önemli değil) 62 | 63 | Özel `&` ön eki, henüz bellek ayrılmış yeni bir yapı için bir işaretçi oluşturur. 64 | 65 | .play moretypes/struct-literals.go 66 | 67 | * Diziler 68 | 69 | `[n]T` türü `T` türündeki `n` tane değerden oluşan bir dizidir. 70 | 71 | var a [10]int 72 | 73 | ifadesi 10 tamsayıdan oluşan dizi türünde bir `a` değişkeni bildirir. 74 | 75 | Dizinin uzunluğu tür bildiriminin bir parçası olduğundan dizi bir kere tanımlandıktan sonra yeniden boyutlandırılamaz. Bu bir kısıtlama gibi görünüyor, fakat endişe etmeyin; 76 | Go dizilerle çalışmak için daha uygun bir yol sunuyor. 77 | 78 | .play moretypes/array.go 79 | 80 | * Dilimler 81 | 82 | Bir dizinin uzunluğu sabittir. 83 | Öte yandan, bir dilim, bir dizinin elemanlarının dinamik boyutlu ve esnek bir görünümü olarak yorumlanabilir. 84 | Dilimler pratikte dizilerden çok daha yaygındır. 85 | 86 | `[]T` türü `T` türünde elemanları olan bir dilim türüdür. 87 | 88 | Aşağıdaki ifade `a` dizisinin ilk beş elemanına ilişkin bir dilim oluşturur: 89 | 90 | a[0:5] 91 | 92 | .play moretypes/slices.go 93 | 94 | * Dilimler dizilere olan başvurular gibidir 95 | 96 | Bir dilim herhangi bir veri barındırmaz, sadece arka plandaki bir dizinin bir kısmını niteler. 97 | 98 | Bir dilimin elemanları değiştirildiğinde arkadaki dizinin karşı düşen elemanlarını da değiştirir. 99 | 100 | Bu değişiklikler arka planda aynı diziyi kullanan diğer dilimlerde de görünür. 101 | 102 | .play moretypes/slices-pointers.go 103 | 104 | * Dilim literalleri 105 | 106 | Bir dilim literali uzunluğun belirtilmediği bir dizi literali gibidir. 107 | 108 | İşte bir dizi literali: 109 | 110 | [3]bool{true, true, false} 111 | 112 | ve şimdi yukarıdaki dizinin aynısını yarattıktan sonra bu diziye başvuran bir dilim oluşturalım: 113 | 114 | []bool{true, true, false} 115 | 116 | .play moretypes/slice-literals.go 117 | 118 | * Dilim öntanımlıları 119 | 120 | Dilimleme yaparken üst ve alt sınırları, öntanımlılar kullanılacak şekilde atlayabilirsiniz. 121 | 122 | Öntanımlılar alt sınır için sıfır, üst sınır için ise dilim uzunluğudur. 123 | 124 | Şu dizi ele alındığında 125 | 126 | var a [10]int 127 | 128 | aşağıdaki dilim ifadeleri eşdeğerdir: 129 | 130 | a[0:10] 131 | a[:10] 132 | a[0:] 133 | a[:] 134 | 135 | .play moretypes/slice-bounds.go 136 | 137 | * Dilim uzunluk ve kapasitesi 138 | 139 | Bir dilim hem bir _uzunluk_ hem de bir _kapasite_ niteliğine sahiptir. 140 | 141 | Bir dilimin uzunluğu dilimin içerdiği elemanların sayısıdır. 142 | 143 | Bir dilimin kapasitesi saymaya dilimdeki ilk elemandan başlamak kaydıyla, arka plandaki dizide bulunan elemanların sayısıdır. 144 | 145 | Bir `s` diliminin uzunluk ve kapasitesi `len(s)` ve `cap(s)` ifadeleriyle öğrenilebilir. 146 | 147 | Dilimi genişletmek için tekrar dilimleme yapabilirsiniz, dilimin yeterli kapasiteye sahip olması kaydıyla. 148 | Örnek programdaki dilim işlemlerinden birini, dilimi kapasitesinin üzerinde genişletecek yönde değiştirin ve ne olduğunu görün. 149 | 150 | .play moretypes/slice-len-cap.go 151 | 152 | * Boş dilimler 153 | 154 | Boş bir dilim `nil` değerini alır. 155 | 156 | Boş ("nil") bir dilimin uzunluk ve kapasite değeri 0'dır. 157 | 158 | .play moretypes/nil-slices.go 159 | 160 | * Dilim oluşturmak 161 | 162 | Dilimler yerleşik `make` fonksiyonu ile oluşturulur; dinamik uzunluklu dizileri böyle oluştururuz. 163 | 164 | `make` fonksiyonu bellekte sıfırlanmış bir dizi ayırır ve bu diziyi işaret eden bir dilim döndürür: 165 | 166 | a := make([]int, 5) // len(a)=5 167 | 168 | Kapasite belirtmek için, `make` fonksiyonuna üçüncü bir argüman geçirin: 169 | 170 | b := make([]int, 0, 5) // len(b)=0, cap(b)=5 171 | 172 | b = b[:cap(b)] // len(b)=5, cap(b)=5 173 | b = b[1:] // len(b)=4, cap(b)=4 174 | 175 | .play moretypes/making-slices.go 176 | 177 | * Dilim Dilimleri 178 | 179 | Dilimler herhangi bir türde eleman içerebilir, başka dilimler de dahil. 180 | 181 | .play moretypes/slices-of-slice.go 182 | 183 | * Dilime eleman ekleme 184 | 185 | Bir dilime yeni elemanlar eklemek sık yapılan bir işlemdir. Bu nedenle Go, `append` adında yerleşik bir fonksiyon sunar. 186 | [[https://golang.org/pkg/builtin/#append][Dokümantasyonda]], yerleşik ögelerin bulunduğu `builtin` paketindeki `append` fonksiyonu şöyle tanımlanmıştır: 187 | 188 | func append(s []T, vs ...T) []T 189 | 190 | `append` fonksiyonunun ilk parametresi olan `s` `T` türünden bir dilimdir ve geri kalan diğer tüm `T` dilimleri bu dilime eklenir. 191 | 192 | `append` fonksiyonu, fonksiyona ilk giren dilim değeri ve diğer eklenen dilim değerlerinin hepsini içeren bir dilim döndürür. 193 | 194 | Eğer `s` dizisinin değeri girilen değerleri saklayamayacak kadar küçük ise daha büyük bir dizi alanı ayrılır ve fonksiyonun döndürdüğü dilim yeni ayrılmış alanı gösterir. 195 | 196 | (Dilimler hakkında daha çok şey öğrenmek için [[https://blog.golang.org/go-slices-usage-and-internals][Dilimler: kullanım ve içyüzü]] makalesini okuyun.) 197 | 198 | .play moretypes/append.go 199 | 200 | * Range 201 | 202 | `for` döngüsünün `range` ("aralık") formu ile bir dilim ("slice") veya eşlem ("map") üzerinde dolaşılır. 203 | 204 | Bir dilim üzerinde dolaşılırken her seferinde iki değer dönülür. 205 | İlki indis, ikincisi o indisli elemanın bir kopyası. 206 | 207 | .play moretypes/range.go 208 | 209 | * Range devam 210 | 211 | Değer dizisinin indislerini veya o indise karşılık gelen değerleri `_` ataması ile atlayabilirsiniz. 212 | 213 | Yalnızca indisi kullanmak istiyorsanız ", value" kısmını tamamen çıkarınız. 214 | 215 | .play moretypes/range-continued.go 216 | 217 | * Alıştırma: Dilimler 218 | 219 | `Pic` fonksiyonunu gerçekleyin. Fonksiyonunuz, `dx` 8 bitlik işaretsiz bir tamsayı olmak üzere, her bir elemanı `dx` elemanlı dilimlerden oluşan `dy` uzunluğunda bir dilim döndürmelidir. Program çalıştırıldığında, tamsayılar grilik ölçeğine (veya mavilik ölçeğine) karşı düşen değerler olarak yorumlanarak bir resim görüntülenecektir. 220 | 221 | Resim seçimi size ait. Kullanabileceğiniz bazı ilginç işlemler: `x^y`, `(x+y)/2` ve `x*y`. 222 | 223 | (`[][]uint8` içerisindeki her `[]uint8` dilimine bellek ayırmak için döngü kullanmanız gerekmektedir.) 224 | 225 | (Türler arasında dönüşüm yapmak için `uint8(intValue)` ifadesini kullanın.) 226 | 227 | .play moretypes/exercise-slices.go 228 | 229 | * Eşlemler 230 | 231 | Bir eşlem ("map"), anahtarları ("keys") değerlere ("values") eşler. 232 | 233 | Bir eşlemin "sıfır değeri" `nil`'dir. Bir `nil` eşleminde anahtar bulunmadığı gibi anahtar da oluşturulamaz. 234 | 235 | `make` fonksiyonu verilen türde, ilklendirilmiş ve kullanıma hazır durumda bir eşlem döner. 236 | 237 | .play moretypes/maps.go 238 | 239 | * Eşlem değerleri 240 | 241 | Eşlem değerleri ("map literals") yapı değerleriyle ("struct literals") benzerlik gösterir; fakat anahtar kullanımı zorunludur. 242 | 243 | .play moretypes/map-literals.go 244 | 245 | * Eşlem değerleri devam 246 | 247 | Eğer tepe seviyedeki tür yalnızca bir tür adı ise, bunu atlayabilirsiniz. 248 | 249 | .play moretypes/map-literals-continued.go 250 | 251 | * Eşlemleri değiştirme 252 | 253 | `m` eşlemine bir eleman ekle ya da varolan bir elemanı değiştir: 254 | 255 | m[key] = elem 256 | 257 | Bir elemana eriş: 258 | 259 | elem = m[key] 260 | 261 | Bir eleman sil: 262 | 263 | delete(m, key) 264 | 265 | Anahtarın mevcut olup olmadığını iki-değerli atama ile sına: 266 | 267 | elem, ok = m[key] 268 | 269 | Eğer `key`, `m` içindeyse `ok`, `true` değerini alır. Aksi halde `ok`, `false` değerini alır. 270 | 271 | Benzer şekilde, `key` eşlemde bulunmuyorsa `elem` eşlemin eleman türü için belirlenmiş sıfır değerini alır. 272 | 273 | _Not_: eğer `elem` veya `ok` henüz bildirilmemişse bir kısa bildirim biçimi kullanabilirsiniz: 274 | 275 | elem, ok := m[key] 276 | 277 | .play moretypes/mutating-maps.go 278 | 279 | * Alıştırma: Eşlemler 280 | 281 | `WordCount` fonksiyonunu gerçekleyin. Fonksiyonunuz `s` dizgisinin içerisindeki her bir “kelime” adedi için bir eşlem döndürmelidir. `wc.Test` fonksiyonu, fonksiyonunuzu test edecek ve fonksiyonunuzun başarılı ya da başarısız olduğunu çıktı olarak verecektir. 282 | 283 | [[https://golang.org/pkg/strings/#Fields][strings.Fields]] size yardımcı 284 | olabilir. 285 | 286 | .play moretypes/exercise-maps.go 287 | 288 | * Fonksiyon değerleri 289 | 290 | Fonksiyonlar da birer değerdir. Tıpkı diğer değerler gibi bir yerden bir yere aktarılabilirler. 291 | 292 | Fonksiyon değerleri fonksiyonun argümanları veya dönüş değerleri olarak kullanılabilir. 293 | 294 | .play moretypes/function-values.go 295 | 296 | * Fonksiyon kaplamları 297 | 298 | Go fonksiyonları kaplam ("closure") olabilirler. Kaplam, kendi bloğunun dışındaki değişkenlere erişen bir fonksiyon değeridir. Fonksiyon bu değerlere erişip atama yapabilir; yani bir bakıma bu fonksiyon o değerler ile aynı kapsamdadır. 299 | 300 | Bu örnekte; `adder` fonksiyonu bir kaplam döndürür. Her kaplam kendi `sum` değişkeni ile aynı kapsamdadır. 301 | 302 | .play moretypes/function-closures.go 303 | 304 | * Alıştırma: Fibonacci kaplamı 305 | 306 | Hadi fonksiyonlar ile biraz eğlenelim. 307 | 308 | Öyle bir `fibonacci` fonksiyonu tasarlayın ki ardışık [[https://en.wikipedia.org/wiki/Fibonacci_number][fibonacci sayıları]] (0, 1, 1, 2, 3, 5, ...) döndüren bir fonksiyon (kaplam) döndürsün. 309 | 310 | .play moretypes/exercise-fibonacci-closure.go 311 | 312 | * Tebrikler! 313 | 314 | Bu dersin sonuna geldiniz! 315 | 316 | Daha neler öğreneceğinizi görmek için [[/list][bölüm listesine]] geri dönün ya da [[javascript:click('.next-page')][bir sonraki derse]] geçin. 317 | -------------------------------------------------------------------------------- /content/moretypes/append.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var s []int 9 | printSlice(s) 10 | 11 | // append works on nil slices. 12 | s = append(s, 0) 13 | printSlice(s) 14 | 15 | // The slice grows as needed. 16 | s = append(s, 1) 17 | printSlice(s) 18 | 19 | // We can add more than one element at a time. 20 | s = append(s, 2, 3, 4) 21 | printSlice(s) 22 | } 23 | 24 | func printSlice(s []int) { 25 | fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) 26 | } 27 | -------------------------------------------------------------------------------- /content/moretypes/array.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var a [2]string 9 | a[0] = "Hello" 10 | a[1] = "World" 11 | fmt.Println(a[0], a[1]) 12 | fmt.Println(a) 13 | 14 | primes := [6]int{2, 3, 5, 7, 11, 13} 15 | fmt.Println(primes) 16 | } 17 | -------------------------------------------------------------------------------- /content/moretypes/exercise-fibonacci-closure.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | // fibonacci is a function that returns 8 | // a function that returns an int. 9 | func fibonacci() func() int { 10 | } 11 | 12 | func main() { 13 | f := fibonacci() 14 | for i := 0; i < 10; i++ { 15 | fmt.Println(f()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /content/moretypes/exercise-maps.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "golang.org/x/tour/wc" 7 | ) 8 | 9 | func WordCount(s string) map[string]int { 10 | return map[string]int{"x": 1} 11 | } 12 | 13 | func main() { 14 | wc.Test(WordCount) 15 | } 16 | -------------------------------------------------------------------------------- /content/moretypes/exercise-slices.go: -------------------------------------------------------------------------------- 1 | // +build no-build OMIT 2 | 3 | package main 4 | 5 | import "golang.org/x/tour/pic" 6 | 7 | func Pic(dx, dy int) [][]uint8 { 8 | } 9 | 10 | func main() { 11 | pic.Show(Pic) 12 | } 13 | -------------------------------------------------------------------------------- /content/moretypes/function-closures.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func adder() func(int) int { 8 | sum := 0 9 | return func(x int) int { 10 | sum += x 11 | return sum 12 | } 13 | } 14 | 15 | func main() { 16 | pos, neg := adder(), adder() 17 | for i := 0; i < 10; i++ { 18 | fmt.Println( 19 | pos(i), 20 | neg(-2*i), 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /content/moretypes/function-values.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | func compute(fn func(float64, float64) float64) float64 { 11 | return fn(3, 4) 12 | } 13 | 14 | func main() { 15 | hypot := func(x, y float64) float64 { 16 | return math.Sqrt(x*x + y*y) 17 | } 18 | fmt.Println(hypot(5, 12)) 19 | 20 | fmt.Println(compute(hypot)) 21 | fmt.Println(compute(math.Pow)) 22 | } 23 | -------------------------------------------------------------------------------- /content/moretypes/making-slices.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | a := make([]int, 5) 9 | printSlice("a", a) 10 | 11 | b := make([]int, 0, 5) 12 | printSlice("b", b) 13 | 14 | c := b[:2] 15 | printSlice("c", c) 16 | 17 | d := c[2:5] 18 | printSlice("d", d) 19 | } 20 | 21 | func printSlice(s string, x []int) { 22 | fmt.Printf("%s len=%d cap=%d %v\n", 23 | s, len(x), cap(x), x) 24 | } 25 | -------------------------------------------------------------------------------- /content/moretypes/map-literals-continued.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | Lat, Long float64 9 | } 10 | 11 | var m = map[string]Vertex{ 12 | "Bell Labs": {40.68433, -74.39967}, 13 | "Google": {37.42202, -122.08408}, 14 | } 15 | 16 | func main() { 17 | fmt.Println(m) 18 | } 19 | -------------------------------------------------------------------------------- /content/moretypes/map-literals.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | Lat, Long float64 9 | } 10 | 11 | var m = map[string]Vertex{ 12 | "Bell Labs": Vertex{ 13 | 40.68433, -74.39967, 14 | }, 15 | "Google": Vertex{ 16 | 37.42202, -122.08408, 17 | }, 18 | } 19 | 20 | func main() { 21 | fmt.Println(m) 22 | } 23 | -------------------------------------------------------------------------------- /content/moretypes/maps.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | Lat, Long float64 9 | } 10 | 11 | var m map[string]Vertex 12 | 13 | func main() { 14 | m = make(map[string]Vertex) 15 | m["Bell Labs"] = Vertex{ 16 | 40.68433, -74.39967, 17 | } 18 | fmt.Println(m["Bell Labs"]) 19 | } 20 | -------------------------------------------------------------------------------- /content/moretypes/mutating-maps.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | m := make(map[string]int) 9 | 10 | m["Answer"] = 42 11 | fmt.Println("The value:", m["Answer"]) 12 | 13 | m["Answer"] = 48 14 | fmt.Println("The value:", m["Answer"]) 15 | 16 | delete(m, "Answer") 17 | fmt.Println("The value:", m["Answer"]) 18 | 19 | v, ok := m["Answer"] 20 | fmt.Println("The value:", v, "Present?", ok) 21 | } 22 | -------------------------------------------------------------------------------- /content/moretypes/nil-slices.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | var s []int 9 | fmt.Println(s, len(s), cap(s)) 10 | if s == nil { 11 | fmt.Println("nil!") 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /content/moretypes/pointers.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | i, j := 42, 2701 9 | 10 | p := &i // point to i 11 | fmt.Println(*p) // read i through the pointer 12 | *p = 21 // set i through the pointer 13 | fmt.Println(i) // see the new value of i 14 | 15 | p = &j // point to j 16 | *p = *p / 37 // divide j through the pointer 17 | fmt.Println(j) // see the new value of j 18 | } 19 | -------------------------------------------------------------------------------- /content/moretypes/range-continued.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | pow := make([]int, 10) 9 | for i := range pow { 10 | pow[i] = 1 << uint(i) // == 2**i 11 | } 12 | for _, value := range pow { 13 | fmt.Printf("%d\n", value) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /content/moretypes/range.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} 8 | 9 | func main() { 10 | for i, v := range pow { 11 | fmt.Printf("2**%d = %d\n", i, v) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /content/moretypes/slice-bounds.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | s := []int{2, 3, 5, 7, 11, 13} 9 | 10 | s = s[1:4] 11 | fmt.Println(s) 12 | 13 | s = s[:2] 14 | fmt.Println(s) 15 | 16 | s = s[1:] 17 | fmt.Println(s) 18 | } 19 | -------------------------------------------------------------------------------- /content/moretypes/slice-len-cap.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | s := []int{2, 3, 5, 7, 11, 13} 9 | printSlice(s) 10 | 11 | // Slice the slice to give it zero length. 12 | s = s[:0] 13 | printSlice(s) 14 | 15 | // Extend its length. 16 | s = s[:4] 17 | printSlice(s) 18 | 19 | // Drop its first two values. 20 | s = s[2:] 21 | printSlice(s) 22 | } 23 | 24 | func printSlice(s []int) { 25 | fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) 26 | } 27 | -------------------------------------------------------------------------------- /content/moretypes/slice-literals.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | q := []int{2, 3, 5, 7, 11, 13} 9 | fmt.Println(q) 10 | 11 | r := []bool{true, false, true, true, false, true} 12 | fmt.Println(r) 13 | 14 | s := []struct { 15 | i int 16 | b bool 17 | }{ 18 | {2, true}, 19 | {3, false}, 20 | {5, true}, 21 | {7, true}, 22 | {11, false}, 23 | {13, true}, 24 | } 25 | fmt.Println(s) 26 | } 27 | -------------------------------------------------------------------------------- /content/moretypes/slices-of-slice.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | // Create a tic-tac-toe board. 12 | board := [][]string{ 13 | []string{"_", "_", "_"}, 14 | []string{"_", "_", "_"}, 15 | []string{"_", "_", "_"}, 16 | } 17 | 18 | // The players take turns. 19 | board[0][0] = "X" 20 | board[2][2] = "O" 21 | board[1][2] = "X" 22 | board[1][0] = "O" 23 | board[0][2] = "X" 24 | 25 | for i := 0; i < len(board); i++ { 26 | fmt.Printf("%s\n", strings.Join(board[i], " ")) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /content/moretypes/slices-pointers.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | names := [4]string{ 9 | "John", 10 | "Paul", 11 | "George", 12 | "Ringo", 13 | } 14 | fmt.Println(names) 15 | 16 | a := names[0:2] 17 | b := names[1:3] 18 | fmt.Println(a, b) 19 | 20 | b[0] = "XXX" 21 | fmt.Println(a, b) 22 | fmt.Println(names) 23 | } 24 | -------------------------------------------------------------------------------- /content/moretypes/slices.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | primes := [6]int{2, 3, 5, 7, 11, 13} 9 | 10 | var s []int = primes[1:4] 11 | fmt.Println(s) 12 | } 13 | -------------------------------------------------------------------------------- /content/moretypes/struct-fields.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | X int 9 | Y int 10 | } 11 | 12 | func main() { 13 | v := Vertex{1, 2} 14 | v.X = 4 15 | fmt.Println(v.X) 16 | } 17 | -------------------------------------------------------------------------------- /content/moretypes/struct-literals.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | X, Y int 9 | } 10 | 11 | var ( 12 | v1 = Vertex{1, 2} // has type Vertex 13 | v2 = Vertex{X: 1} // Y:0 is implicit 14 | v3 = Vertex{} // X:0 and Y:0 15 | p = &Vertex{1, 2} // has type *Vertex 16 | ) 17 | 18 | func main() { 19 | fmt.Println(v1, p, v2, v3) 20 | } 21 | -------------------------------------------------------------------------------- /content/moretypes/struct-pointers.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | X int 9 | Y int 10 | } 11 | 12 | func main() { 13 | v := Vertex{1, 2} 14 | p := &v 15 | p.X = 1e9 16 | fmt.Println(v) 17 | } 18 | -------------------------------------------------------------------------------- /content/moretypes/structs.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | type Vertex struct { 8 | X int 9 | Y int 10 | } 11 | 12 | func main() { 13 | fmt.Println(Vertex{1, 2}) 14 | } 15 | -------------------------------------------------------------------------------- /content/welcome.article: -------------------------------------------------------------------------------- 1 | Hoşgeldiniz! 2 | Bu turu nasıl kullanacağınızı öğrenin: diğer derslere nasıl geçiş yapacağınızı ve kodları nasıl çalıştıracağınızı. 3 | 4 | Go Yazarları Sunar 5 | https://golang.org 6 | 7 | * Merhaba, 世界 8 | 9 | [[https://golang.org/][Go programlama dili]] turuna hoşgeldiniz. 10 | 11 | Tur bir dizi bölümlerden oluşmaktadır. 12 | Sayfanın sol üst köşesindeki [[javascript:highlight(".logo")][Go Turu]] yazısına tıklayarak ilgili bölümlere erişim sağlayabilirsiniz. 13 | 14 | Ayrıca sayfanın sağ üst köşesindeki [[javascript:highlightAndClick(".nav")][menü]] yazısına tıklayarak da tüm tur içeriğini görebilirsiniz. 15 | 16 | Turumuz boyunca, slaytlar ve tamamlamanız için sunulmuş alıştırmalar ile karşılaşacaksınız. 17 | 18 | Bunların arasında gezinmek için şu yöntemleri kullanın: 19 | 20 | - Bir önceki sayfaya gitmek için [[javascript:highlight(".prev-page")]["önceki"]] veya `PageUp`, 21 | 22 | - Bir sonraki sayfaya gitmek için [[javascript:highlight(".next-page")]["sonraki"]] veya `PageDown` . 23 | 24 | Turumuz etkileşimlidir. 25 | Programı 26 | #appengine: uzak sunucuda 27 | kendi bilgisayarınızda çalıştırmak için [[javascript:highlightAndClick("#run")][Çalıştır]] butonuna (veya `shift-enter` tuşlarına basın). Program çıktısını, kodun hemen altında görebilirsiniz. 28 | 29 | Bu örnekler Go dilinin farklı yönlerini açıklamaktadır. Bu programlar Go dili deneyimleriniz için birer başlangıç noktası olarak seçilmiştir. 30 | 31 | Programı düzenleyin ve tekrar çalıştırın. 32 | 33 | [[javascript:highlightAndClick("#format")][Biçimle]] veya `ctrl-enter` tuşlarına bastığınızda, editördeki yazı [[https://golang.org/cmd/gofmt/][gofmt]] aracını kullanarak biçimlendirilir. 34 | Sözdizimi renklendirmesini [[javascript:highlightAndClick(".syntax-checkbox")][Renklendirme]] butonuna basarak açıp kapatabilirsiniz. 35 | 36 | İlerlemeye hazır olduğunuzda, sayfanın altındaki [[javascript:highlightAndClick(".next-page")][sağ oka]] tıklayın ya da `PageDown` tuşuna basın. 37 | 38 | .play welcome/hello.go 39 | 40 | * Dilinizde Go 41 | 42 | Bu tur şu dillerde de mevcuttur: 43 | 44 | - [[https://go-tour-de.appspot.com/][Almanca — Deutsch]] 45 | - [[https://tour.go-zh.org/][Basitleştirilmiş Çince — 中文(简体)]] 46 | - [[https://go-tour-br.appspot.com/][Brezilya Portekizcesi — Português do Brasil]] 47 | - [[https://go-tour-id2.appspot.com/][Endonezce — Bahasa]] 48 | - [[https://go-tour-fr.appspot.com/][Fransızca — Français]] 49 | - [[https://go-tour-zh-tw.appspot.com/][Geleneksel Çince — 中文(繁體)]] 50 | - [[https://go-tour-he.appspot.com/][İbranice — עִבְרִית]] 51 | - [[https://tour.golang.org/][İngilizce — English]] 52 | - [[https://go-tour-es.appspot.com/][İspanyolca — Español]] 53 | - [[https://go-tour-ita.appspot.com/][İtalyanca — Italiano]] 54 | - [[https://go-tour-jp.appspot.com/][Japonca — 日本語]] 55 | - [[https://go-tour-ca.appspot.com/][Katalanca — Català]] 56 | - [[https://go-tour-kr.appspot.com/][Korece — 한국어]] 57 | - [[https://go-tour-uz.appspot.com/][Özbekçe — Ўзбекча]] 58 | - [[https://go-tour-ro.appspot.com/][Rumence — Româna]] 59 | - [[https://go-tour-turkish.appspot.com/][Türkçe - Türkçe]] 60 | - [[https://go-tour-ua.appspot.com/][Ukraynaca — Українська]] 61 | 62 | Devam etmek için [[javascript:highlightAndClick(".next-page")]["ileri"]] butonuna tıklayın ya da `PageDown` tuşlayın. 63 | 64 | #appengine: * Çevrimdışı Go 65 | #appengine: 66 | #appengine: Bu tur, İnternet erişimi olmadan kullanabileceğiniz bağımsız bir program 67 | #appengine: halinde de mevcuttur. 68 | #appengine: 69 | #appengine: Bağımsız tur, kodları kendi makinenizde inşa edip çalıştırdığından 70 | #appengine: daha hızlıdır. 71 | #appengine: 72 | #appengine: Tur'u yerelde çalıştırmak için öncelikle 73 | #appengine: [[http://golang.org/dl/][Go'yu indirin ve kurun]] 74 | #appengine: ve Tur'u komut satırında başlatın: 75 | #appengine: 76 | #appengine: go tool tour 77 | #appengine: 78 | #appengine: Tur programı Tur'un yerel sürümünü görüntüleyen bir web tarayıcı 79 | #appengine: açacaktır 80 | #appengine: 81 | #appengine: Veya dilerseniz Tur'a bu web sitesi üzerinden devam edebilirsiniz. 82 | 83 | #appengine: * Go Playground 84 | #appengine: 85 | #appengine: Bu tur [[https://golang.org/][golang.org]] sunucuları üzerinde çalışan 86 | #appengine: [[https://play.golang.org/][Go Playground]] web servisi üzerine kurulmuştur. 87 | #appengine: 88 | #appengine: Servis, Go programını, bir korunaklı sanal alan ("sandbox") içerisine alıp, 89 | #appengine: derler, bağlar, çalıştırır ve bu programın çıktısını döndürür. 90 | #appengine: 91 | #appengine: Playground içinde çalıştırılabilen programlar birtakım kısıtlamalara maruz kalır: 92 | #appengine: 93 | #appengine: - Playground standart kütüphanenin çoğunu; ağ ve dosya sistemi erişimi eksiklikleri 94 | #appengine: gibi göze çarpan bazı istisnalar dışında, kullanabilir. Bu nedenle, 95 | #appengine: playground programının dış dünyayla tek iletişimi "standard output" ve 96 | #appengine: "standard error"dur. 97 | #appengine: 98 | #appengine: - Playground'ta zamanın başlangıcı 2009-11-10 23:00:00 UTC tarihine 99 | #appengine: karşılık gelir (bu tarihin öneminin ne olduğunu bulmak okuyucu için 100 | #appengine: alıştırma niteliğindedir). Bu, programlara rastgele olmayan çıktılar 101 | #appengine: vererek önbelleğe alınmalarını kolaylaştırır. 102 | #appengine: 103 | #appengine: - Yürütme zamanı ("execution time"), işlemci, bellek kullanımında da kısıtlamalar 104 | #appengine: mevcuttur ve program dış ağ sunucularına erişemez. 105 | #appengine: 106 | #appengine: Playground, Go'nun en son kararlı sürümünü kullanır. 107 | #appengine: 108 | #appengine: Daha fazla bilgi için "[[https://blog.golang.org/playground][Inside the Go Playground]]" 109 | #appengine: kaynağını okuyun. 110 | #appengine: 111 | #appengine: .play welcome/sandbox.go 112 | 113 | * Tebrikler 114 | 115 | Turun ilk bölümünü bitirdiniz! 116 | 117 | Şimdi Go hakkında daha neler öğrenebileceğinizi görmek için [[javascript:highlightAndClick(".logo")][Go Turu]] logosuna veya bir sonraki derse doğrudan gitmek için [[javascript:click('.next-page')][bir sonraki ders]] yazısına tıklayın. 118 | -------------------------------------------------------------------------------- /content/welcome/hello.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import "fmt" 6 | 7 | func main() { 8 | fmt.Println("Hello, 世界") 9 | } 10 | -------------------------------------------------------------------------------- /content/welcome/sandbox.go: -------------------------------------------------------------------------------- 1 | // +build OMIT 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | fmt.Println("Welcome to the playground!") 12 | 13 | fmt.Println("The time is", time.Now()) 14 | } 15 | -------------------------------------------------------------------------------- /gotour/appengine.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine 6 | 7 | package main 8 | 9 | import ( 10 | "bufio" 11 | "bytes" 12 | "io" 13 | "net/http" 14 | "strings" 15 | 16 | "appengine" 17 | 18 | _ "golang.org/x/tools/playground" 19 | ) 20 | 21 | const runUrl = "http://golang.org/compile" 22 | 23 | func init() { 24 | http.Handle("/lesson/", hstsHandler(lessonHandler)) 25 | http.Handle("/", hstsHandler(rootHandler)) 26 | 27 | if err := initTour(".", "HTTPTransport"); err != nil { 28 | panic(err) 29 | } 30 | } 31 | 32 | func rootHandler(w http.ResponseWriter, r *http.Request) { 33 | c := appengine.NewContext(r) 34 | if err := renderUI(w); err != nil { 35 | c.Criticalf("UI render: %v", err) 36 | } 37 | } 38 | 39 | func lessonHandler(w http.ResponseWriter, r *http.Request) { 40 | c := appengine.NewContext(r) 41 | lesson := strings.TrimPrefix(r.URL.Path, "/lesson/") 42 | if err := writeLesson(lesson, w); err != nil { 43 | if err == lessonNotFound { 44 | http.NotFound(w, r) 45 | } else { 46 | c.Criticalf("tour render: %v", err) 47 | } 48 | } 49 | } 50 | 51 | // prepContent returns a Reader that produces the content from the given 52 | // Reader, but strips the prefix "#appengine: " from each line. It also drops 53 | // any non-blank like that follows a series of 1 or more lines with the prefix. 54 | func prepContent(in io.Reader) io.Reader { 55 | var prefix = []byte("#appengine: ") 56 | out, w := io.Pipe() 57 | go func() { 58 | r := bufio.NewReader(in) 59 | drop := false 60 | for { 61 | b, err := r.ReadBytes('\n') 62 | if err != nil && err != io.EOF { 63 | w.CloseWithError(err) 64 | return 65 | } 66 | if bytes.HasPrefix(b, prefix) { 67 | b = b[len(prefix):] 68 | drop = true 69 | } else if drop { 70 | if len(b) > 1 { 71 | b = nil 72 | } 73 | drop = false 74 | } 75 | if len(b) > 0 { 76 | w.Write(b) 77 | } 78 | if err == io.EOF { 79 | w.Close() 80 | return 81 | } 82 | } 83 | }() 84 | return out 85 | } 86 | 87 | // socketAddr returns the WebSocket handler address. 88 | // The App Engine version does not provide a WebSocket handler. 89 | func socketAddr() string { return "" } 90 | 91 | // hstsHandler wraps an http.HandlerFunc such that it sets the HSTS header. 92 | func hstsHandler(fn http.HandlerFunc) http.Handler { 93 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 94 | w.Header().Set("Strict-Transport-Security", "max-age=31536000; preload") 95 | fn(w, r) 96 | }) 97 | } 98 | -------------------------------------------------------------------------------- /gotour/fmt.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main 6 | 7 | import ( 8 | "bytes" 9 | "encoding/json" 10 | "go/ast" 11 | "go/parser" 12 | "go/printer" 13 | "go/token" 14 | "net/http" 15 | ) 16 | 17 | func init() { 18 | http.HandleFunc("/fmt", fmtHandler) 19 | } 20 | 21 | type fmtResponse struct { 22 | Body string 23 | Error string 24 | } 25 | 26 | func fmtHandler(w http.ResponseWriter, r *http.Request) { 27 | resp := new(fmtResponse) 28 | body, err := gofmt(r.FormValue("body")) 29 | if err != nil { 30 | resp.Error = err.Error() 31 | } else { 32 | resp.Body = body 33 | } 34 | json.NewEncoder(w).Encode(resp) 35 | } 36 | 37 | func gofmt(body string) (string, error) { 38 | fset := token.NewFileSet() 39 | f, err := parser.ParseFile(fset, "prog.go", body, parser.ParseComments) 40 | if err != nil { 41 | return "", err 42 | } 43 | ast.SortImports(fset, f) 44 | var buf bytes.Buffer 45 | config := &printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8} 46 | err = config.Fprint(&buf, fset, f) 47 | if err != nil { 48 | return "", err 49 | } 50 | return buf.String(), nil 51 | } 52 | -------------------------------------------------------------------------------- /gotour/local.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !appengine 6 | 7 | package main 8 | 9 | import ( 10 | "flag" 11 | "fmt" 12 | "go/build" 13 | "io" 14 | "log" 15 | "net" 16 | "net/http" 17 | "net/url" 18 | "os" 19 | "os/exec" 20 | "path/filepath" 21 | "runtime" 22 | "strings" 23 | "time" 24 | 25 | "golang.org/x/tools/playground/socket" 26 | 27 | // Imports so that go build/install automatically installs them. 28 | _ "golang.org/x/tour/pic" 29 | _ "golang.org/x/tour/tree" 30 | _ "golang.org/x/tour/wc" 31 | ) 32 | 33 | const ( 34 | basePkg = "golang.org/x/tour/" 35 | socketPath = "/socket" 36 | ) 37 | 38 | var ( 39 | httpListen = flag.String("http", "127.0.0.1:3999", "host:port to listen on") 40 | openBrowser = flag.Bool("openbrowser", true, "open browser automatically") 41 | ) 42 | 43 | var ( 44 | // GOPATH containing the tour packages 45 | gopath = os.Getenv("GOPATH") 46 | 47 | httpAddr string 48 | ) 49 | 50 | // isRoot reports whether path is the root directory of the tour tree. 51 | // To be the root, it must have content and template subdirectories. 52 | func isRoot(path string) bool { 53 | _, err := os.Stat(filepath.Join(path, "content", "welcome.article")) 54 | if err == nil { 55 | _, err = os.Stat(filepath.Join(path, "template", "index.tmpl")) 56 | } 57 | return err == nil 58 | } 59 | 60 | func findRoot() (string, error) { 61 | ctx := build.Default 62 | p, err := ctx.Import(basePkg, "", build.FindOnly) 63 | if err == nil && isRoot(p.Dir) { 64 | return p.Dir, nil 65 | } 66 | tourRoot := filepath.Join(runtime.GOROOT(), "misc", "tour") 67 | ctx.GOPATH = tourRoot 68 | p, err = ctx.Import(basePkg, "", build.FindOnly) 69 | if err == nil && isRoot(tourRoot) { 70 | gopath = tourRoot 71 | return tourRoot, nil 72 | } 73 | return "", fmt.Errorf("could not find go-tour content; check $GOROOT and $GOPATH") 74 | } 75 | 76 | func main() { 77 | flag.Parse() 78 | 79 | // find and serve the go tour files 80 | root, err := findRoot() 81 | if err != nil { 82 | log.Fatalf("Couldn't find tour files: %v", err) 83 | } 84 | 85 | log.Println("Serving content from", root) 86 | 87 | host, port, err := net.SplitHostPort(*httpListen) 88 | if err != nil { 89 | log.Fatal(err) 90 | } 91 | if host == "" { 92 | host = "localhost" 93 | } 94 | if host != "127.0.0.1" && host != "localhost" { 95 | log.Print(localhostWarning) 96 | } 97 | httpAddr = host + ":" + port 98 | 99 | if err := initTour(root, "SocketTransport"); err != nil { 100 | log.Fatal(err) 101 | } 102 | 103 | http.HandleFunc("/", rootHandler) 104 | http.HandleFunc("/lesson/", lessonHandler) 105 | 106 | origin := &url.URL{Scheme: "http", Host: host + ":" + port} 107 | http.Handle(socketPath, socket.NewHandler(origin)) 108 | 109 | // Keep these static file handlers in sync with ../app.yaml. 110 | static := http.FileServer(http.Dir(root)) 111 | http.Handle("/content/img/", static) 112 | http.Handle("/static/", static) 113 | imgDir := filepath.Join(root, "static", "img") 114 | http.Handle("/favicon.ico", http.FileServer(http.Dir(imgDir))) 115 | 116 | go func() { 117 | url := "http://" + httpAddr 118 | if waitServer(url) && *openBrowser && startBrowser(url) { 119 | log.Printf("A browser window should open. If not, please visit %s", url) 120 | } else { 121 | log.Printf("Please open your web browser and visit %s", url) 122 | } 123 | }() 124 | log.Fatal(http.ListenAndServe(httpAddr, nil)) 125 | } 126 | 127 | // rootHandler returns a handler for all the requests except the ones for lessons. 128 | func rootHandler(w http.ResponseWriter, r *http.Request) { 129 | if err := renderUI(w); err != nil { 130 | log.Println(err) 131 | } 132 | } 133 | 134 | // lessonHandler handler the HTTP requests for lessons. 135 | func lessonHandler(w http.ResponseWriter, r *http.Request) { 136 | lesson := strings.TrimPrefix(r.URL.Path, "/lesson/") 137 | if err := writeLesson(lesson, w); err != nil { 138 | if err == lessonNotFound { 139 | http.NotFound(w, r) 140 | } else { 141 | log.Println(err) 142 | } 143 | } 144 | } 145 | 146 | const localhostWarning = ` 147 | WARNING! WARNING! WARNING! 148 | 149 | I appear to be listening on an address that is not localhost. 150 | Anyone with access to this address and port will have access 151 | to this machine as the user running gotour. 152 | 153 | If you don't understand this message, hit Control-C to terminate this process. 154 | 155 | WARNING! WARNING! WARNING! 156 | ` 157 | 158 | type response struct { 159 | Output string `json:"output"` 160 | Errors string `json:"compile_errors"` 161 | } 162 | 163 | func init() { 164 | socket.Environ = environ 165 | } 166 | 167 | // environ returns the original execution environment with GOPATH 168 | // replaced (or added) with the value of the global var gopath. 169 | func environ() (env []string) { 170 | for _, v := range os.Environ() { 171 | if !strings.HasPrefix(v, "GOPATH=") { 172 | env = append(env, v) 173 | } 174 | } 175 | env = append(env, "GOPATH="+gopath) 176 | return 177 | } 178 | 179 | // waitServer waits some time for the http Server to start 180 | // serving url. The return value reports whether it starts. 181 | func waitServer(url string) bool { 182 | tries := 20 183 | for tries > 0 { 184 | resp, err := http.Get(url) 185 | if err == nil { 186 | resp.Body.Close() 187 | return true 188 | } 189 | time.Sleep(100 * time.Millisecond) 190 | tries-- 191 | } 192 | return false 193 | } 194 | 195 | // startBrowser tries to open the URL in a browser, and returns 196 | // whether it succeed. 197 | func startBrowser(url string) bool { 198 | // try to start the browser 199 | var args []string 200 | switch runtime.GOOS { 201 | case "darwin": 202 | args = []string{"open"} 203 | case "windows": 204 | args = []string{"cmd", "/c", "start"} 205 | default: 206 | args = []string{"xdg-open"} 207 | } 208 | cmd := exec.Command(args[0], append(args[1:], url)...) 209 | return cmd.Start() == nil 210 | } 211 | 212 | // prepContent for the local tour simply returns the content as-is. 213 | func prepContent(r io.Reader) io.Reader { return r } 214 | 215 | // socketAddr returns the WebSocket handler address. 216 | func socketAddr() string { return "ws://" + httpAddr + socketPath } 217 | -------------------------------------------------------------------------------- /gotour/tour.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package main // import "golang.org/x/tour/gotour" 6 | 7 | import ( 8 | "bytes" 9 | "crypto/sha1" 10 | "encoding/base64" 11 | "encoding/json" 12 | "fmt" 13 | "html/template" 14 | "io" 15 | "io/ioutil" 16 | "net/http" 17 | "os" 18 | "path/filepath" 19 | "strings" 20 | "time" 21 | 22 | "golang.org/x/tools/godoc/static" 23 | "golang.org/x/tools/present" 24 | ) 25 | 26 | var ( 27 | uiContent []byte 28 | lessons = make(map[string][]byte) 29 | lessonNotFound = fmt.Errorf("lesson not found") 30 | ) 31 | 32 | // initTour loads tour.article and the relevant HTML templates from the given 33 | // tour root, and renders the template to the tourContent global variable. 34 | func initTour(root, transport string) error { 35 | // Make sure playground is enabled before rendering. 36 | present.PlayEnabled = true 37 | 38 | // Set up templates. 39 | action := filepath.Join(root, "template", "action.tmpl") 40 | tmpl, err := present.Template().ParseFiles(action) 41 | if err != nil { 42 | return fmt.Errorf("parse templates: %v", err) 43 | } 44 | 45 | // Init lessons. 46 | contentPath := filepath.Join(root, "content") 47 | if err := initLessons(tmpl, contentPath); err != nil { 48 | return fmt.Errorf("init lessons: %v", err) 49 | } 50 | 51 | // Init UI 52 | index := filepath.Join(root, "template", "index.tmpl") 53 | ui, err := template.ParseFiles(index) 54 | if err != nil { 55 | return fmt.Errorf("parse index.tmpl: %v", err) 56 | } 57 | buf := new(bytes.Buffer) 58 | 59 | data := struct { 60 | SocketAddr string 61 | Transport template.JS 62 | }{socketAddr(), template.JS(transport)} 63 | 64 | if err := ui.Execute(buf, data); err != nil { 65 | return fmt.Errorf("render UI: %v", err) 66 | } 67 | uiContent = buf.Bytes() 68 | 69 | return initScript(root) 70 | } 71 | 72 | // initLessonss finds all the lessons in the passed directory, renders them, 73 | // using the given template and saves the content in the lessons map. 74 | func initLessons(tmpl *template.Template, content string) error { 75 | dir, err := os.Open(content) 76 | if err != nil { 77 | return err 78 | } 79 | files, err := dir.Readdirnames(0) 80 | if err != nil { 81 | return err 82 | } 83 | for _, f := range files { 84 | if filepath.Ext(f) != ".article" { 85 | continue 86 | } 87 | content, err := parseLesson(tmpl, filepath.Join(content, f)) 88 | if err != nil { 89 | return fmt.Errorf("parsing %v: %v", f, err) 90 | } 91 | name := strings.TrimSuffix(f, ".article") 92 | lessons[name] = content 93 | } 94 | return nil 95 | } 96 | 97 | // File defines the JSON form of a code file in a page. 98 | type File struct { 99 | Name string 100 | Content string 101 | Hash string 102 | } 103 | 104 | // Page defines the JSON form of a tour lesson page. 105 | type Page struct { 106 | Title string 107 | Content string 108 | Files []File 109 | } 110 | 111 | // Lesson defines the JSON form of a tour lesson. 112 | type Lesson struct { 113 | Title string 114 | Description string 115 | Pages []Page 116 | } 117 | 118 | // parseLesson parses and returns a lesson content given its name and 119 | // the template to render it. 120 | func parseLesson(tmpl *template.Template, path string) ([]byte, error) { 121 | f, err := os.Open(path) 122 | if err != nil { 123 | return nil, err 124 | } 125 | defer f.Close() 126 | doc, err := present.Parse(prepContent(f), path, 0) 127 | if err != nil { 128 | return nil, err 129 | } 130 | 131 | lesson := Lesson{ 132 | doc.Title, 133 | doc.Subtitle, 134 | make([]Page, len(doc.Sections)), 135 | } 136 | 137 | for i, sec := range doc.Sections { 138 | p := &lesson.Pages[i] 139 | w := new(bytes.Buffer) 140 | if err := sec.Render(w, tmpl); err != nil { 141 | return nil, fmt.Errorf("render section: %v", err) 142 | } 143 | p.Title = sec.Title 144 | p.Content = w.String() 145 | codes := findPlayCode(sec) 146 | p.Files = make([]File, len(codes)) 147 | for i, c := range codes { 148 | f := &p.Files[i] 149 | f.Name = c.FileName 150 | f.Content = string(c.Raw) 151 | hash := sha1.Sum(c.Raw) 152 | f.Hash = base64.StdEncoding.EncodeToString(hash[:]) 153 | } 154 | } 155 | 156 | w := new(bytes.Buffer) 157 | if err := json.NewEncoder(w).Encode(lesson); err != nil { 158 | return nil, fmt.Errorf("encode lesson: %v", err) 159 | } 160 | return w.Bytes(), nil 161 | } 162 | 163 | // findPlayCode returns a slide with all the Code elements in the given 164 | // Elem with Play set to true. 165 | func findPlayCode(e present.Elem) []*present.Code { 166 | var r []*present.Code 167 | switch v := e.(type) { 168 | case present.Code: 169 | if v.Play { 170 | r = append(r, &v) 171 | } 172 | case present.Section: 173 | for _, s := range v.Elem { 174 | r = append(r, findPlayCode(s)...) 175 | } 176 | } 177 | return r 178 | } 179 | 180 | // writeLesson writes the tour content to the provided Writer. 181 | func writeLesson(name string, w io.Writer) error { 182 | if uiContent == nil { 183 | panic("writeLesson called before successful initTour") 184 | } 185 | if len(name) == 0 { 186 | return writeAllLessons(w) 187 | } 188 | l, ok := lessons[name] 189 | if !ok { 190 | return lessonNotFound 191 | } 192 | _, err := w.Write(l) 193 | return err 194 | } 195 | 196 | func writeAllLessons(w io.Writer) error { 197 | if _, err := fmt.Fprint(w, "{"); err != nil { 198 | return err 199 | } 200 | nLessons := len(lessons) 201 | for k, v := range lessons { 202 | if _, err := fmt.Fprintf(w, "%q:%s", k, v); err != nil { 203 | return err 204 | } 205 | nLessons-- 206 | if nLessons != 0 { 207 | if _, err := fmt.Fprint(w, ","); err != nil { 208 | return err 209 | } 210 | } 211 | } 212 | _, err := fmt.Fprint(w, "}") 213 | return err 214 | } 215 | 216 | // renderUI writes the tour UI to the provided Writer. 217 | func renderUI(w io.Writer) error { 218 | if uiContent == nil { 219 | panic("renderUI called before successful initTour") 220 | } 221 | _, err := w.Write(uiContent) 222 | return err 223 | } 224 | 225 | // nocode returns true if the provided Section contains 226 | // no Code elements with Play enabled. 227 | func nocode(s present.Section) bool { 228 | for _, e := range s.Elem { 229 | if c, ok := e.(present.Code); ok && c.Play { 230 | return false 231 | } 232 | } 233 | return true 234 | } 235 | 236 | // initScript concatenates all the javascript files needed to render 237 | // the tour UI and serves the result on /script.js. 238 | func initScript(root string) error { 239 | modTime := time.Now() 240 | b := new(bytes.Buffer) 241 | 242 | content, ok := static.Files["playground.js"] 243 | if !ok { 244 | return fmt.Errorf("playground.js not found in static files") 245 | } 246 | b.WriteString(content) 247 | 248 | // Keep this list in dependency order 249 | files := []string{ 250 | "static/lib/jquery.min.js", 251 | "static/lib/jquery-ui.min.js", 252 | "static/lib/angular.min.js", 253 | "static/lib/codemirror/lib/codemirror.js", 254 | "static/lib/codemirror/mode/go/go.js", 255 | "static/lib/angular-ui.min.js", 256 | "static/js/app.js", 257 | "static/js/controllers.js", 258 | "static/js/directives.js", 259 | "static/js/services.js", 260 | "static/js/values.js", 261 | } 262 | 263 | for _, file := range files { 264 | f, err := ioutil.ReadFile(filepath.Join(root, file)) 265 | if err != nil { 266 | return fmt.Errorf("couldn't open %v: %v", file, err) 267 | } 268 | _, err = b.Write(f) 269 | if err != nil { 270 | return fmt.Errorf("error concatenating %v: %v", file, err) 271 | } 272 | } 273 | 274 | http.HandleFunc("/script.js", func(w http.ResponseWriter, r *http.Request) { 275 | w.Header().Set("Content-type", "application/javascript") 276 | // Set expiration time in one week. 277 | w.Header().Set("Cache-control", "max-age=604800") 278 | http.ServeContent(w, r, "", modTime, bytes.NewReader(b.Bytes())) 279 | }) 280 | 281 | return nil 282 | } 283 | -------------------------------------------------------------------------------- /pic/pic.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package pic // import "golang.org/x/tour/pic" 6 | 7 | import ( 8 | "bytes" 9 | "encoding/base64" 10 | "fmt" 11 | "image" 12 | "image/png" 13 | ) 14 | 15 | func Show(f func(int, int) [][]uint8) { 16 | const ( 17 | dx = 256 18 | dy = 256 19 | ) 20 | data := f(dx, dy) 21 | m := image.NewNRGBA(image.Rect(0, 0, dx, dy)) 22 | for y := 0; y < dy; y++ { 23 | for x := 0; x < dx; x++ { 24 | v := data[y][x] 25 | i := y*m.Stride + x*4 26 | m.Pix[i] = v 27 | m.Pix[i+1] = v 28 | m.Pix[i+2] = 255 29 | m.Pix[i+3] = 255 30 | } 31 | } 32 | ShowImage(m) 33 | } 34 | 35 | func ShowImage(m image.Image) { 36 | var buf bytes.Buffer 37 | err := png.Encode(&buf, m) 38 | if err != nil { 39 | panic(err) 40 | } 41 | enc := base64.StdEncoding.EncodeToString(buf.Bytes()) 42 | fmt.Println("IMAGE:" + enc) 43 | } 44 | -------------------------------------------------------------------------------- /reader/validate.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package reader // import "golang.org/x/tour/reader" 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "os" 11 | ) 12 | 13 | func Validate(r io.Reader) { 14 | b := make([]byte, 1024, 2048) 15 | i, o := 0, 0 16 | for ; i < 1<<20 && o < 1<<20; i++ { // test 1mb 17 | n, err := r.Read(b) 18 | for i, v := range b[:n] { 19 | if v != 'A' { 20 | fmt.Fprintf(os.Stderr, "got byte %x at offset %v, want 'A'\n", v, o+i) 21 | return 22 | } 23 | } 24 | o += n 25 | if err != nil { 26 | fmt.Fprintf(os.Stderr, "read error: %v\n", err) 27 | return 28 | } 29 | } 30 | if o == 0 { 31 | fmt.Fprintf(os.Stderr, "read zero bytes after %d Read calls\n", i) 32 | return 33 | } 34 | fmt.Println("OK!") 35 | } 36 | -------------------------------------------------------------------------------- /solutions/README: -------------------------------------------------------------------------------- 1 | This directory contains the solutions to the exercises presented in the Go tour. 2 | 3 | IMPORTANT: The main point of the Go tour is to challenge you, so please try to 4 | solve all problems by yourself before reading these solutions!!! 5 | 6 | In any case, these are not the only valid solutions. But they have been reviewed 7 | by the Go team. Therefore you can use them as a guide on how to solve the 8 | most basic problems in Go. 9 | -------------------------------------------------------------------------------- /solutions/binarytrees.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | 12 | "golang.org/x/tour/tree" 13 | ) 14 | 15 | func walkImpl(t *tree.Tree, ch chan int) { 16 | if t == nil { 17 | return 18 | } 19 | walkImpl(t.Left, ch) 20 | ch <- t.Value 21 | walkImpl(t.Right, ch) 22 | } 23 | 24 | // Walk walks the tree t sending all values 25 | // from the tree to the channel ch. 26 | func Walk(t *tree.Tree, ch chan int) { 27 | walkImpl(t, ch) 28 | // Need to close the channel here 29 | close(ch) 30 | } 31 | 32 | // Same determines whether the trees 33 | // t1 and t2 contain the same values. 34 | // NOTE: The implementation leaks goroutines when trees are different. 35 | // See binarytrees_quit.go for a better solution. 36 | func Same(t1, t2 *tree.Tree) bool { 37 | w1, w2 := make(chan int), make(chan int) 38 | 39 | go Walk(t1, w1) 40 | go Walk(t2, w2) 41 | 42 | for { 43 | v1, ok1 := <-w1 44 | v2, ok2 := <-w2 45 | if !ok1 || !ok2 { 46 | return ok1 == ok2 47 | } 48 | if v1 != v2 { 49 | return false 50 | } 51 | } 52 | } 53 | 54 | func main() { 55 | fmt.Print("tree.New(1) == tree.New(1): ") 56 | if Same(tree.New(1), tree.New(1)) { 57 | fmt.Println("PASSED") 58 | } else { 59 | fmt.Println("FAILED") 60 | } 61 | 62 | fmt.Print("tree.New(1) != tree.New(2): ") 63 | if !Same(tree.New(1), tree.New(2)) { 64 | fmt.Println("PASSED") 65 | } else { 66 | fmt.Println("FAILED") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /solutions/binarytrees_quit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | 12 | "golang.org/x/tour/tree" 13 | ) 14 | 15 | func walkImpl(t *tree.Tree, ch, quit chan int) { 16 | if t == nil { 17 | return 18 | } 19 | walkImpl(t.Left, ch, quit) 20 | select { 21 | case ch <- t.Value: 22 | // Value successfully sent. 23 | case <-quit: 24 | return 25 | } 26 | walkImpl(t.Right, ch, quit) 27 | } 28 | 29 | // Walk walks the tree t sending all values 30 | // from the tree to the channel ch. 31 | func Walk(t *tree.Tree, ch, quit chan int) { 32 | walkImpl(t, ch, quit) 33 | close(ch) 34 | } 35 | 36 | // Same determines whether the trees 37 | // t1 and t2 contain the same values. 38 | func Same(t1, t2 *tree.Tree) bool { 39 | w1, w2 := make(chan int), make(chan int) 40 | quit := make(chan int) 41 | defer close(quit) 42 | 43 | go Walk(t1, w1, quit) 44 | go Walk(t2, w2, quit) 45 | 46 | for { 47 | v1, ok1 := <-w1 48 | v2, ok2 := <-w2 49 | if !ok1 || !ok2 { 50 | return ok1 == ok2 51 | } 52 | if v1 != v2 { 53 | return false 54 | } 55 | } 56 | } 57 | 58 | func main() { 59 | fmt.Print("tree.New(1) == tree.New(1): ") 60 | if Same(tree.New(1), tree.New(1)) { 61 | fmt.Println("PASSED") 62 | } else { 63 | fmt.Println("FAILED") 64 | } 65 | 66 | fmt.Print("tree.New(1) != tree.New(2): ") 67 | if !Same(tree.New(1), tree.New(2)) { 68 | fmt.Println("PASSED") 69 | } else { 70 | fmt.Println("FAILED") 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /solutions/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "math" 12 | ) 13 | 14 | type ErrNegativeSqrt float64 15 | 16 | func (e ErrNegativeSqrt) Error() string { 17 | return fmt.Sprintf("Sqrt: negative number %g", e) 18 | } 19 | 20 | const delta = 1e-10 21 | 22 | func Sqrt(f float64) (float64, error) { 23 | if f < 0 { 24 | return 0, ErrNegativeSqrt(f) 25 | } 26 | z := f 27 | for { 28 | n := z - (z*z-f)/(2*z) 29 | if math.Abs(n-z) < delta { 30 | break 31 | } 32 | z = n 33 | } 34 | return z, nil 35 | } 36 | 37 | func main() { 38 | fmt.Println(Sqrt(2)) 39 | fmt.Println(Sqrt(-2)) 40 | } 41 | -------------------------------------------------------------------------------- /solutions/fib.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import "fmt" 10 | 11 | // fibonacci is a function that returns 12 | // a function that returns an int. 13 | func fibonacci() func() int { 14 | f, g := 0, 1 15 | return func() int { 16 | f, g = g, f+g 17 | return f 18 | } 19 | } 20 | 21 | func main() { 22 | f := fibonacci() 23 | for i := 0; i < 10; i++ { 24 | fmt.Println(f()) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /solutions/http.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "log" 12 | "net/http" 13 | ) 14 | 15 | type String string 16 | 17 | func (s String) ServeHTTP(w http.ResponseWriter, r *http.Request) { 18 | fmt.Fprint(w, s) 19 | } 20 | 21 | type Struct struct { 22 | Greeting string 23 | Punct string 24 | Who string 25 | } 26 | 27 | func (s *Struct) ServeHTTP(w http.ResponseWriter, r *http.Request) { 28 | fmt.Fprintf(w, "%s%s %s", s.Greeting, s.Punct, s.Who) 29 | } 30 | 31 | func main() { 32 | http.Handle("/string", String("I'm a frayed knot.")) 33 | http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"}) 34 | err := http.ListenAndServe("localhost:4000", nil) 35 | if err != nil { 36 | log.Fatal(err) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /solutions/image.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "image" 11 | "image/color" 12 | 13 | "golang.org/x/tour/pic" 14 | ) 15 | 16 | type Image struct { 17 | Height, Width int 18 | } 19 | 20 | func (m Image) ColorModel() color.Model { 21 | return color.RGBAModel 22 | } 23 | 24 | func (m Image) Bounds() image.Rectangle { 25 | return image.Rect(0, 0, m.Height, m.Width) 26 | } 27 | 28 | func (m Image) At(x, y int) color.Color { 29 | c := uint8(x ^ y) 30 | return color.RGBA{c, c, 255, 255} 31 | } 32 | 33 | func main() { 34 | m := Image{256, 256} 35 | pic.ShowImage(m) 36 | } 37 | -------------------------------------------------------------------------------- /solutions/loops.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "math" 12 | ) 13 | 14 | const delta = 1e-6 15 | 16 | func Sqrt(x float64) float64 { 17 | z := x 18 | n := 0.0 19 | for math.Abs(n-z) > delta { 20 | n, z = z, z-(z*z-x)/(2*z) 21 | } 22 | return z 23 | } 24 | 25 | func main() { 26 | const x = 2 27 | mine, theirs := Sqrt(x), math.Sqrt(x) 28 | fmt.Println(mine, theirs, mine-theirs) 29 | } 30 | -------------------------------------------------------------------------------- /solutions/maps.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "strings" 11 | 12 | "golang.org/x/tour/wc" 13 | ) 14 | 15 | func WordCount(s string) map[string]int { 16 | m := make(map[string]int) 17 | for _, f := range strings.Fields(s) { 18 | m[f]++ 19 | } 20 | return m 21 | } 22 | 23 | func main() { 24 | wc.Test(WordCount) 25 | } 26 | -------------------------------------------------------------------------------- /solutions/rot13.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "io" 11 | "os" 12 | "strings" 13 | ) 14 | 15 | func rot13(b byte) byte { 16 | var a, z byte 17 | switch { 18 | case 'a' <= b && b <= 'z': 19 | a, z = 'a', 'z' 20 | case 'A' <= b && b <= 'Z': 21 | a, z = 'A', 'Z' 22 | default: 23 | return b 24 | } 25 | return (b-a+13)%(z-a+1) + a 26 | } 27 | 28 | type rot13Reader struct { 29 | r io.Reader 30 | } 31 | 32 | func (r rot13Reader) Read(p []byte) (n int, err error) { 33 | n, err = r.r.Read(p) 34 | for i := 0; i < n; i++ { 35 | p[i] = rot13(p[i]) 36 | } 37 | return 38 | } 39 | 40 | func main() { 41 | s := strings.NewReader( 42 | "Lbh penpxrq gur pbqr!") 43 | r := rot13Reader{s} 44 | io.Copy(os.Stdout, &r) 45 | } 46 | -------------------------------------------------------------------------------- /solutions/slices.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import "golang.org/x/tour/pic" 10 | 11 | func Pic(dx, dy int) [][]uint8 { 12 | p := make([][]uint8, dy) 13 | for i := range p { 14 | p[i] = make([]uint8, dx) 15 | } 16 | 17 | for y, row := range p { 18 | for x := range row { 19 | row[x] = uint8(x * y) 20 | } 21 | } 22 | 23 | return p 24 | } 25 | 26 | func main() { 27 | pic.Show(Pic) 28 | } 29 | -------------------------------------------------------------------------------- /solutions/stringers.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import "fmt" 10 | 11 | type IPAddr [4]byte 12 | 13 | func (ip IPAddr) String() string { 14 | return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]) 15 | } 16 | 17 | func main() { 18 | addrs := map[string]IPAddr{ 19 | "loopback": {127, 0, 0, 1}, 20 | "googleDNS": {8, 8, 8, 8}, 21 | } 22 | for n, a := range addrs { 23 | fmt.Printf("%v: %v\n", n, a) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /solutions/webcrawler.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "errors" 11 | "fmt" 12 | "sync" 13 | ) 14 | 15 | type Fetcher interface { 16 | // Fetch returns the body of URL and 17 | // a slice of URLs found on that page. 18 | Fetch(url string) (body string, urls []string, err error) 19 | } 20 | 21 | // fetched tracks URLs that have been (or are being) fetched. 22 | // The lock must be held while reading from or writing to the map. 23 | // See http://golang.org/ref/spec#Struct_types section on embedded types. 24 | var fetched = struct { 25 | m map[string]error 26 | sync.Mutex 27 | }{m: make(map[string]error)} 28 | 29 | var loading = errors.New("url load in progress") // sentinel value 30 | 31 | // Crawl uses fetcher to recursively crawl 32 | // pages starting with url, to a maximum of depth. 33 | func Crawl(url string, depth int, fetcher Fetcher) { 34 | if depth <= 0 { 35 | fmt.Printf("<- Done with %v, depth 0.\n", url) 36 | return 37 | } 38 | 39 | fetched.Lock() 40 | if _, ok := fetched.m[url]; ok { 41 | fetched.Unlock() 42 | fmt.Printf("<- Done with %v, already fetched.\n", url) 43 | return 44 | } 45 | // We mark the url to be loading to avoid others reloading it at the same time. 46 | fetched.m[url] = loading 47 | fetched.Unlock() 48 | 49 | // We load it concurrently. 50 | body, urls, err := fetcher.Fetch(url) 51 | 52 | // And update the status in a synced zone. 53 | fetched.Lock() 54 | fetched.m[url] = err 55 | fetched.Unlock() 56 | 57 | if err != nil { 58 | fmt.Printf("<- Error on %v: %v\n", url, err) 59 | return 60 | } 61 | fmt.Printf("Found: %s %q\n", url, body) 62 | done := make(chan bool) 63 | for i, u := range urls { 64 | fmt.Printf("-> Crawling child %v/%v of %v : %v.\n", i, len(urls), url, u) 65 | go func(url string) { 66 | Crawl(url, depth-1, fetcher) 67 | done <- true 68 | }(u) 69 | } 70 | for i, u := range urls { 71 | fmt.Printf("<- [%v] %v/%v Waiting for child %v.\n", url, i, len(urls), u) 72 | <-done 73 | } 74 | fmt.Printf("<- Done with %v\n", url) 75 | } 76 | 77 | func main() { 78 | Crawl("http://golang.org/", 4, fetcher) 79 | 80 | fmt.Println("Fetching stats\n--------------") 81 | for url, err := range fetched.m { 82 | if err != nil { 83 | fmt.Printf("%v failed: %v\n", url, err) 84 | } else { 85 | fmt.Printf("%v was fetched\n", url) 86 | } 87 | } 88 | } 89 | 90 | // fakeFetcher is Fetcher that returns canned results. 91 | type fakeFetcher map[string]*fakeResult 92 | 93 | type fakeResult struct { 94 | body string 95 | urls []string 96 | } 97 | 98 | func (f *fakeFetcher) Fetch(url string) (string, []string, error) { 99 | if res, ok := (*f)[url]; ok { 100 | return res.body, res.urls, nil 101 | } 102 | return "", nil, fmt.Errorf("not found: %s", url) 103 | } 104 | 105 | // fetcher is a populated fakeFetcher. 106 | var fetcher = &fakeFetcher{ 107 | "http://golang.org/": &fakeResult{ 108 | "The Go Programming Language", 109 | []string{ 110 | "http://golang.org/pkg/", 111 | "http://golang.org/cmd/", 112 | }, 113 | }, 114 | "http://golang.org/pkg/": &fakeResult{ 115 | "Packages", 116 | []string{ 117 | "http://golang.org/", 118 | "http://golang.org/cmd/", 119 | "http://golang.org/pkg/fmt/", 120 | "http://golang.org/pkg/os/", 121 | }, 122 | }, 123 | "http://golang.org/pkg/fmt/": &fakeResult{ 124 | "Package fmt", 125 | []string{ 126 | "http://golang.org/", 127 | "http://golang.org/pkg/", 128 | }, 129 | }, 130 | "http://golang.org/pkg/os/": &fakeResult{ 131 | "Package os", 132 | []string{ 133 | "http://golang.org/", 134 | "http://golang.org/pkg/", 135 | }, 136 | }, 137 | } 138 | -------------------------------------------------------------------------------- /static/css/app.css: -------------------------------------------------------------------------------- 1 | /* Generic elements */ 2 | html, body { 3 | margin: 0; 4 | padding: 0; 5 | font-size: 16px; 6 | height: 100%; 7 | font-family: sans-serif; 8 | line-height: 24px; 9 | word-wrap: break-word; 10 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 11 | /* Prevent font scaling in landscape */ 12 | -webkit-text-size-adjust: none; 13 | -webkit-font-smoothing: antialiased; 14 | } 15 | * { 16 | outline: none; 17 | } 18 | a { 19 | color: #375eab; 20 | text-decoration: none; 21 | } 22 | a.logo, .toc a { 23 | color: inherit; 24 | } 25 | h1, h2, h3, h4 { 26 | color: #333; 27 | line-height: 32px; 28 | margin: 0; 29 | } 30 | pre, code { 31 | font-family: 'Inconsolata', monospace; 32 | border-radius: 4px; 33 | color: #333; 34 | background-color: #fafafa; 35 | } 36 | pre { 37 | padding: 10px; 38 | } 39 | code { 40 | padding: 2px; 41 | } 42 | .left { 43 | display: block; 44 | float: left; 45 | margin-right: 10px; 46 | } 47 | .right { 48 | display: block; 49 | float: right; 50 | margin-left: 10px; 51 | } 52 | .bar { 53 | display: block; 54 | overflow: hidden; 55 | -moz-user-select: none; 56 | -webkit-user-select: none; 57 | -ms-user-select: none; 58 | user-select: none; 59 | } 60 | .wrapper { 61 | position: fixed; 62 | overflow: auto; 63 | top: 48px; 64 | bottom: 0; 65 | left: 0; 66 | right: 0; 67 | } 68 | .container { 69 | max-width: 800px; 70 | width: 90%; 71 | margin: 0 auto 36px auto; 72 | padding: 16px 5%; 73 | background: #ffffff; 74 | } 75 | .container a { 76 | color: #375eab; 77 | } 78 | .relative-content { 79 | display: block; 80 | position: relative; 81 | height: 100%; 82 | } 83 | .highlight { 84 | background: #b5533b !important; 85 | color: yellow !important; 86 | } 87 | .hidden { 88 | display: none; 89 | } 90 | p { 91 | margin: 16px 0; 92 | } 93 | li { 94 | margin: 8px 0; 95 | } 96 | ul { 97 | list-style: none; 98 | margin: 0; 99 | padding-left: 32px; 100 | } 101 | /* Navigation bars */ 102 | .top-bar { 103 | position: fixed; 104 | left: 0; 105 | right: 0; 106 | top: 0; 107 | z-index: 1000; 108 | font-size: 1.4em; 109 | padding: 8px 24px; 110 | line-height: 32px; 111 | color: #222; 112 | background: #E0EBF5; 113 | } 114 | .nav { 115 | float: right; 116 | padding: 2px; 117 | height: 25px; 118 | width: 25px; 119 | margin-left: 10px; 120 | cursor: pointer; 121 | fill: #375eab; 122 | } 123 | .nav:hover { 124 | fill: #ffffff; 125 | } 126 | /* Module list */ 127 | .page-header { 128 | font-size: 1.2em; 129 | line-height: 32px; 130 | margin: 32px 0; 131 | } 132 | @media (max-width: 515px) { 133 | .page-header { 134 | font-size: 0.75em; 135 | } 136 | } 137 | .module { 138 | margin: 32px 0; 139 | } 140 | .module-title { 141 | font-size: 1.3em; 142 | font-weight: bold; 143 | color: #333; 144 | margin: 0; 145 | } 146 | .lesson { 147 | background: #E0EBF5; 148 | padding: 8px 16px; 149 | margin: 16px 0; 150 | position: relative; 151 | } 152 | .lesson-title { 153 | display: inline-block; 154 | font-size: 1.2em; 155 | font-weight: bold; 156 | margin: 16px 0 0 0; 157 | padding-right: 48px; 158 | } 159 | /* Lesson viewer */ 160 | .slide-content { 161 | padding: 16px; 162 | background: #fff; 163 | } 164 | .module-bar { 165 | font-size: 1.5em; 166 | padding: 8px 0; 167 | text-align: center; 168 | line-height: 24px; 169 | font-size: 24px; 170 | } 171 | .module-bar a { 172 | color: #375eab; 173 | position: relative; 174 | font-weight: bold; 175 | margin: 5px; 176 | } 177 | .menu-button { 178 | display: inline-block; 179 | text-decoration: none; 180 | cursor: pointer; 181 | font-size: 0.9em; 182 | border-radius: 2px; 183 | background-color: #E0EBF5; 184 | border: 1px solid rgba(0, 0, 0, 0.1); 185 | margin: 2px; 186 | height: 24px; 187 | padding: 1px 8px; 188 | line-height: 24px; 189 | color: #444; 190 | -moz-user-select: none; 191 | -webkit-user-select: none; 192 | -ms-user-select: none; 193 | user-select: none; 194 | } 195 | .menu-button:hover:not(.active) { 196 | border: 1px solid #C6C6C6; 197 | background-color: #fafafa; 198 | } 199 | .menu-button.active { 200 | background: #fff; 201 | } 202 | .menu-button[syntax-checkbox]:after { 203 | content: ' kapalı'; 204 | } 205 | .menu-button[syntax-checkbox].active:after { 206 | content: ' açık'; 207 | } 208 | #file-menu .menu-button { 209 | float: right; 210 | } 211 | a#run, a#kill { 212 | background-color: #375eab; 213 | color: #fff; 214 | width: 50px; 215 | text-align: center; 216 | } 217 | #run:hover:not(:active), #kill:hover:not(:active) { 218 | background-color: #fff; 219 | color: #375eab; 220 | } 221 | .output:not(.active) { 222 | display: none; 223 | } 224 | .output > pre { 225 | font-family: 'Inconsolata', monospace; 226 | background: #fafafa; 227 | margin: 0; 228 | } 229 | .output .system { 230 | color: #888; 231 | } 232 | .output .stderr { 233 | color: #D00A0A; 234 | } 235 | .output-menu .menu-button { 236 | float: left; 237 | } 238 | .output-menu, #file-menu { 239 | background: #fafafa; 240 | } 241 | #explorer { 242 | height: 32px; 243 | padding-left: 30px; 244 | background: #fafafa; 245 | } 246 | #explorer .menu-button.active { 247 | cursor: default; 248 | } 249 | #explorer .syntax-checkbox { 250 | float: right; 251 | } 252 | /* CodeMirror */ 253 | #file-editor { 254 | background: #FFFFD8; 255 | overflow: auto; 256 | } 257 | #file-editor > textarea { 258 | display: none; 259 | } 260 | #file-editor .CodeMirror { 261 | height: auto; 262 | } 263 | #file-editor .CodeMirror-lines, #file-editor .CodeMirror-gutters { 264 | background: #FFFFD8; 265 | font-family: 'Inconsolata', monospace; 266 | line-height: 1.2em; 267 | } 268 | .CodeMirror-code > .line-error { 269 | background: #FF8080; 270 | } 271 | .CodeMirror-code > .line-error .CodeMirror-linenumber { 272 | color: #FF5555; 273 | font-weight: bolder; 274 | } 275 | #file-editor .CodeMirror-gutters { 276 | width: 32px; 277 | } 278 | @media (min-width: 601px) { 279 | #editor-container { 280 | position: fixed; 281 | top: 48px; 282 | left: 0px; 283 | right: 0px; 284 | bottom: 0px; 285 | overflow: hidden; 286 | background: #fff; 287 | } 288 | #left-side { 289 | position: absolute; 290 | top: 0; 291 | bottom: 0; 292 | left: 0; 293 | width: 50%; 294 | overflow: hidden; 295 | } 296 | .output { 297 | background-image: url(/static/img/gopher.png); 298 | background-repeat: no-repeat; 299 | background-position: bottom; 300 | background-color: #fff; 301 | } 302 | div[vertical-slide] { 303 | position: absolute; 304 | top: 0px; 305 | bottom: 0px; 306 | width: 5px; 307 | background: #e0ebf5; 308 | left: 50%; 309 | right: 50%; 310 | z-index: 100; 311 | cursor: move; 312 | } 313 | #right-side { 314 | position: absolute; 315 | top: 0; 316 | bottom: 0; 317 | right: 0; 318 | left: 50%; 319 | background: #fff; 320 | } 321 | .slide-content { 322 | position: absolute; 323 | left: 0; 324 | right: 0; 325 | top: 0; 326 | bottom: 30px; 327 | overflow: auto; 328 | } 329 | .module-bar { 330 | position: absolute; 331 | left: 0; 332 | right: 0; 333 | bottom: 0; 334 | padding: 4px 0; 335 | margin: 0; 336 | } 337 | #top-part { 338 | position: absolute; 339 | left: 0; 340 | right: 0; 341 | top: 0; 342 | bottom: 33%; 343 | background: #e0ebf5; 344 | } 345 | #file-editor { 346 | position: absolute; 347 | left: 0; 348 | right: 0; 349 | top: 0; 350 | bottom: 0; 351 | } 352 | div[horizontal-slide] { 353 | position: absolute; 354 | left: 0; 355 | right: 0; 356 | bottom: 33%; 357 | height: 5px; 358 | background: #e0ebf5; 359 | z-index: 100; 360 | cursor: move; 361 | } 362 | #bottom-part { 363 | position: absolute; 364 | left: 0; 365 | right: 0; 366 | bottom: 0; 367 | top: 67%; 368 | min-height: 100px; 369 | z-index: 50; 370 | } 371 | #explorer { 372 | position: absolute; 373 | top: 0; 374 | left: 0; 375 | right: 0; 376 | } 377 | #explorer + div { 378 | top: 32px; 379 | } 380 | #file-menu { 381 | position: absolute; 382 | top: 0; 383 | right: 0; 384 | left: 0; 385 | background: #fafafa; 386 | } 387 | .output { 388 | position: absolute; 389 | top: 34px; 390 | bottom: 0; 391 | left: 0; 392 | right: 0; 393 | margin: 0; 394 | padding: 0; 395 | overflow: auto; 396 | } 397 | } 398 | @media (max-width: 600px) { 399 | #top-part { 400 | border: 1px solid #ccc; 401 | } 402 | #left-side { 403 | background: #e0ebf5; 404 | } 405 | #right-side { 406 | padding-top: 48px; 407 | } 408 | #file-menu { 409 | height: 32px; 410 | } 411 | .output { 412 | background: white; 413 | max-height: 300px; 414 | overflow: auto; 415 | } 416 | #editor-container { 417 | padding-bottom: 40px; 418 | } 419 | .module-bar { 420 | position: fixed; 421 | background: #e0ebf5; 422 | left: 0; 423 | right: 0; 424 | bottom: 0; 425 | z-index: 10; 426 | height: 42px; 427 | padding: 0; 428 | overflow: hidden; 429 | text-align: center; 430 | } 431 | .module-bar * { 432 | display: inline-block; 433 | width: 25%; 434 | font-size: 1.1em; 435 | padding: 8px 0; 436 | } 437 | div[horizontal-slide], div[vertical-slide] { 438 | display: none; 439 | } 440 | } 441 | /* Table of contents */ 442 | .toc { 443 | display: none; 444 | position: fixed; 445 | z-index: 200; 446 | font-size: 1.3em; 447 | top: 48px; 448 | bottom: 0; 449 | right: 0; 450 | width: 500px; 451 | background: #e0ebf5; 452 | color: black; 453 | overflow-y: auto; 454 | padding: 0; 455 | margin: 0; 456 | border-left: 4px solid #e0ebf5; 457 | border-bottom: 4px solid #e0ebf5; 458 | -moz-user-select: none; 459 | -webkit-user-select: none; 460 | -ms-user-select: none; 461 | user-select: none; 462 | } 463 | .click-catcher { 464 | position: fixed; 465 | z-index: -100; 466 | top: 0; 467 | bottom: 0; 468 | left: 0; 469 | right: 10px; /* avoid covering the TOC scroller */ 470 | background: rgba(0, 0, 0, 0); 471 | } 472 | .toc * { 473 | margin: 0; 474 | padding: 0; 475 | font-size: 0.95em; 476 | display: block; 477 | } 478 | .toc span, .toc a { 479 | padding: 4px; 480 | } 481 | .toc-module { 482 | color: #375eab; 483 | background: #e0ebf5; 484 | } 485 | .toc-lesson { 486 | background: #fafafa; 487 | color: #333; 488 | margin: 1px 0; 489 | cursor: pointer; 490 | } 491 | .toc-page { 492 | background: #fff; 493 | color: #333; 494 | padding-left: 4px; 495 | display: list-item; 496 | } 497 | .toc-lesson.active .toc-page { 498 | display: list-item; 499 | } 500 | .toc-page.active { 501 | color: #375eab; 502 | font-weight: bold; 503 | } 504 | @media (max-width: 600px) { 505 | .toc { 506 | position: absolute; 507 | left: 0; 508 | right: 0; 509 | bottom: 0; 510 | width: 100%; 511 | border: none; 512 | } 513 | .toc ul { 514 | width: 100%; 515 | } 516 | .click-catcher { 517 | display: none; 518 | } 519 | } 520 | -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-tr/tour/ed657b3550a3f599ec17ec6e477f311e91cb5e77/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/gopher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/golang-tr/tour/ed657b3550a3f599ec17ec6e477f311e91cb5e77/static/img/gopher.png -------------------------------------------------------------------------------- /static/js/app.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2012 The Go Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style 3 | * license that can be found in the LICENSE file. 4 | */ 5 | 'use strict'; 6 | 7 | angular.module('tour', ['ui', 'tour.services', 'tour.controllers', 'tour.directives', 'tour.values', 'ng']). 8 | 9 | config(['$routeProvider', '$locationProvider', 10 | function($routeProvider, $locationProvider) { 11 | $routeProvider. 12 | when('/', { 13 | redirectTo: '/welcome/1' 14 | }). 15 | when('/list', { 16 | templateUrl: '/static/partials/list.html', 17 | }). 18 | when('/:lessonId/:pageNumber', { 19 | templateUrl: '/static/partials/editor.html', 20 | controller: 'EditorCtrl' 21 | }). 22 | when('/:lessonId', { 23 | redirectTo: '/:lessonId/1' 24 | }). 25 | otherwise({ 26 | redirectTo: '/' 27 | }); 28 | 29 | $locationProvider.html5Mode(true).hashPrefix('!'); 30 | } 31 | ]). 32 | 33 | // handle mapping from old paths (#42) to the new organization. 34 | run(function($rootScope, $location, mapping) { 35 | $rootScope.$on( "$locationChangeStart", function(event, next) { 36 | var url = document.createElement('a'); 37 | url.href = next; 38 | if (url.pathname != '/' || url.hash == '') { 39 | return; 40 | } 41 | $location.hash(''); 42 | var m = mapping[url.hash]; 43 | if (m === undefined) { 44 | console.log('unknown url, redirecting home'); 45 | $location.path('/welcome/1'); 46 | return; 47 | } 48 | $location.path(m); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /static/js/controllers.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2012 The Go Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style 3 | * license that can be found in the LICENSE file. 4 | */ 5 | 'use strict'; 6 | 7 | /* Controllers */ 8 | 9 | 10 | angular.module('tour.controllers', []). 11 | 12 | // Navigation controller 13 | controller('EditorCtrl', ['$scope', '$routeParams', '$location', 'toc', 'i18n', 'run', 'fmt', 'editor', 'analytics', 'storage', 14 | function($scope, $routeParams, $location, toc, i18n, run, fmt, editor, analytics, storage) { 15 | var lessons = []; 16 | toc.lessons.then(function(v) { 17 | lessons = v; 18 | $scope.gotoPage($scope.curPage); 19 | 20 | // Store changes on the current file to local storage. 21 | $scope.$watch(function() { 22 | var f = file(); 23 | return f && f.Content; 24 | }, function(val) { 25 | storage.set(file().Hash, val); 26 | }); 27 | }); 28 | 29 | $scope.toc = toc; 30 | $scope.lessonId = $routeParams.lessonId; 31 | $scope.curPage = parseInt($routeParams.pageNumber); 32 | $scope.curFile = 0; 33 | $scope.job = null; 34 | 35 | $scope.nextPageClick = function(event) { 36 | event.preventDefault(); 37 | $scope.nextPage(); 38 | }; 39 | $scope.prevPageClick = function(event) { 40 | event.preventDefault(); 41 | $scope.prevPage(); 42 | }; 43 | $scope.nextPage = function() { 44 | $scope.gotoPage($scope.curPage + 1); 45 | }; 46 | $scope.prevPage = function() { 47 | $scope.gotoPage($scope.curPage - 1); 48 | }; 49 | $scope.gotoPage = function(page) { 50 | var l = $routeParams.lessonId; 51 | if (page >= 1 && page <= lessons[$scope.lessonId].Pages.length) { 52 | $scope.curPage = page; 53 | } else { 54 | l = (page < 1) ? toc.prevLesson(l) : toc.nextLesson(l); 55 | if (l === '') { // If there's not previous or next 56 | $location.path('/list'); 57 | return; 58 | } 59 | page = (page < 1) ? lessons[l].Pages.length : 1; 60 | } 61 | $location.path('/' + l + '/' + page); 62 | $scope.openFile($scope.curFile); 63 | analytics.trackView(); 64 | }; 65 | $scope.openFile = function(file) { 66 | $scope.curFile = file; 67 | editor.paint(); 68 | }; 69 | 70 | function log(mode, text) { 71 | $('.output.active').html('
' + text + '
'); 72 | } 73 | 74 | function clearOutput() { 75 | $('.output.active').html(''); 76 | } 77 | 78 | function file() { 79 | return lessons[$scope.lessonId].Pages[$scope.curPage - 1].Files[$scope.curFile]; 80 | } 81 | 82 | $scope.run = function() { 83 | log('info', i18n.l('waiting')); 84 | var f = file(); 85 | $scope.job = run(f.Content, $('.output.active > pre')[0], { 86 | path: f.Name 87 | }, function() { 88 | $scope.job = null; 89 | $scope.$apply(); 90 | }); 91 | }; 92 | 93 | $scope.kill = function() { 94 | if ($scope.job !== null) $scope.job.Kill(); 95 | }; 96 | 97 | $scope.format = function() { 98 | log('info', i18n.l('waiting')); 99 | fmt(file().Content).then( 100 | function(data) { 101 | if (data.data.Error !== '') { 102 | log('stderr', data.data.Error); 103 | return; 104 | } 105 | clearOutput(); 106 | file().Content = data.data.Body; 107 | }, 108 | function(error) { 109 | log('stderr', error); 110 | }); 111 | }; 112 | 113 | $scope.reset = function() { 114 | file().Content = file().OrigContent; 115 | }; 116 | } 117 | ]); 118 | -------------------------------------------------------------------------------- /static/js/directives.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2012 The Go Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style 3 | * license that can be found in the LICENSE file. 4 | */ 5 | 'use strict'; 6 | 7 | /* Directives */ 8 | 9 | angular.module('tour.directives', []). 10 | 11 | // onpageup executes the given expression when Page Up is released. 12 | directive('onpageup', function() { 13 | return function(scope, elm, attrs) { 14 | elm.attr('tabindex', 0); 15 | elm.keyup(function(evt) { 16 | var key = evt.which || evt.keyCode; 17 | if (key == 33 && !evt.ctrlKey) { 18 | scope.$apply(attrs.onpageup); 19 | evt.preventDefault(); 20 | } 21 | }); 22 | }; 23 | }). 24 | 25 | // onpagedown executes the given expression when Page Down is released. 26 | directive('onpagedown', function() { 27 | return function(scope, elm, attrs) { 28 | elm.attr('tabindex', 0); 29 | elm.keyup(function(evt) { 30 | var key = evt.which || evt.keyCode; 31 | if (key == 34 && !evt.ctrlKey) { 32 | scope.$apply(attrs.onpagedown); 33 | evt.preventDefault(); 34 | } 35 | }); 36 | }; 37 | }). 38 | 39 | // autofocus sets the focus on the given element when the condition is true. 40 | directive('autofocus', function() { 41 | return function(scope, elm, attrs) { 42 | elm.attr('tabindex', 0); 43 | scope.$watch(function() { 44 | return scope.$eval(attrs.autofocus); 45 | }, function(val) { 46 | if (val === true) $(elm).focus(); 47 | }); 48 | }; 49 | }). 50 | 51 | // syntax-checkbox activates and deactivates 52 | directive('syntaxCheckbox', ['editor', 53 | function(editor) { 54 | return function(scope, elm) { 55 | elm.click(function() { 56 | editor.toggleSyntax(); 57 | scope.$digest(); 58 | }); 59 | scope.editor = editor; 60 | }; 61 | } 62 | ]). 63 | 64 | // verticalSlide creates a sliding separator between the left and right elements. 65 | // e.g.: 66 | // 67 | //
68 | // 69 | directive('verticalSlide', ['editor', 70 | function(editor) { 71 | return function(scope, elm, attrs) { 72 | var moveTo = function(x) { 73 | if (x < 0) { 74 | x = 0; 75 | } 76 | if (x > $(window).width()) { 77 | x = $(window).width(); 78 | } 79 | elm.css('left', x); 80 | $(attrs.left).width(x); 81 | $(attrs.right).offset({ 82 | left: x 83 | }); 84 | editor.x = x; 85 | }; 86 | 87 | elm.draggable({ 88 | axis: 'x', 89 | drag: function(event) { 90 | moveTo(event.clientX); 91 | return true; 92 | }, 93 | containment: 'parent', 94 | }); 95 | 96 | if (editor.x !== undefined) { 97 | moveTo(editor.x); 98 | } 99 | }; 100 | } 101 | ]). 102 | 103 | // horizontalSlide creates a sliding separator between the top and bottom elements. 104 | // 105 | //
106 | //
Some content
107 | directive('horizontalSlide', ['editor', 108 | function(editor) { 109 | return function(scope, elm, attrs) { 110 | var moveTo = function(y) { 111 | var top = $(attrs.top).offset().top; 112 | if (y < top) { 113 | y = top; 114 | } 115 | elm.css('top', y - top); 116 | $(attrs.top).height(y - top); 117 | $(attrs.bottom).offset({ 118 | top: y, 119 | height: 0 120 | }); 121 | editor.y = y; 122 | }; 123 | elm.draggable({ 124 | axis: 'y', 125 | drag: function(event) { 126 | moveTo(event.clientY); 127 | return true; 128 | }, 129 | containment: 'parent', 130 | }); 131 | 132 | if (editor.y !== undefined) { 133 | moveTo(editor.y); 134 | } 135 | }; 136 | } 137 | ]). 138 | 139 | directive('tableOfContentsButton', ['i18n', function(i18n) { 140 | var speed = 250; 141 | return { 142 | restrict: 'A', 143 | templateUrl: '/static/partials/toc-button.html', 144 | link: function(scope, elm, attrs) { 145 | scope.tocMessage = i18n.l('toc'); 146 | elm.on('click', function() { 147 | var toc = $(attrs.tableOfContentsButton); 148 | // hide all non active lessons before displaying the toc. 149 | var visible = toc.css('display') != 'none'; 150 | if (!visible) { 151 | toc.find('.toc-lesson:not(.active) .toc-page').hide(); 152 | toc.find('.toc-lesson.active .toc-page').show(); 153 | } 154 | toc.toggle('slide', { 155 | direction: 'right' 156 | }, speed); 157 | 158 | // if fullscreen hide the rest of the content when showing the atoc. 159 | var fullScreen = toc.width() == $(window).width(); 160 | if (fullScreen) $('#editor-container')[visible ? 'show' : 'hide'](); 161 | }); 162 | } 163 | }; 164 | }]). 165 | 166 | // side bar with dynamic table of contents 167 | directive('tableOfContents', ['$routeParams', 'toc', 168 | function($routeParams, toc) { 169 | var speed = 250; 170 | return { 171 | restrict: 'A', 172 | templateUrl: '/static/partials/toc.html', 173 | link: function(scope, elm) { 174 | scope.toc = toc; 175 | scope.params = $routeParams; 176 | 177 | scope.toggleLesson = function(id) { 178 | var l = $('#toc-l-' + id + ' .toc-page'); 179 | l[l.css('display') == 'none' ? 'slideDown' : 'slideUp'](); 180 | }; 181 | 182 | scope.$watch(function() { 183 | return scope.params.lessonId + scope.params.lessonId; 184 | }, function() { 185 | $('.toc-lesson:not(#toc-l-' + scope.params.lessonId + ') .toc-page').slideUp(speed); 186 | }); 187 | 188 | scope.hideTOC = function(fullScreenOnly) { 189 | var fullScreen = elm.find('.toc').width() == $(window).width(); 190 | if (fullScreenOnly && !fullScreen) { 191 | return; 192 | } 193 | $('.toc').toggle('slide', { 194 | direction: 'right' 195 | }, speed); 196 | $('#editor-container').show(); 197 | }; 198 | } 199 | }; 200 | } 201 | ]). 202 | 203 | directive('feedbackButton', ['i18n', function(i18n) { 204 | return { 205 | restrict: 'A', 206 | templateUrl: '/static/partials/feedback-button.html', 207 | link: function(scope, elm, attrs) { 208 | scope.feedbackMessage = i18n.l('submit-feedback'); 209 | 210 | elm.on('click', function() { 211 | var context = window.location.pathname === '/list' 212 | ? '/list' 213 | : '/' + scope.params.lessonId + '/' + scope.params.pageNumber; 214 | context = window.location.protocol + '//' + window.location.host + context; 215 | var title = i18n.l('issue-title'); 216 | var body = i18n.l('context') + ': '+ context + '\n\n'+ i18n.l('issue-message'); 217 | var url = 'https://' + i18n.l('github-repo') + '/issues/new' 218 | + '?title=' + encodeURIComponent(title) 219 | + '&body=' + encodeURIComponent(body); 220 | window.open(url); 221 | }); 222 | } 223 | }; 224 | }]); 225 | -------------------------------------------------------------------------------- /static/js/services.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2012 The Go Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style 3 | * license that can be found in the LICENSE file. 4 | */ 5 | 'use strict'; 6 | 7 | /* Services */ 8 | 9 | angular.module('tour.services', []). 10 | 11 | // Google Analytics 12 | factory('analytics', ['$window', 13 | function(win) { 14 | var track = win.trackPageview || (function() {}); 15 | return { 16 | trackView: track 17 | }; 18 | } 19 | ]). 20 | 21 | // Internationalization 22 | factory('i18n', ['translation', 23 | function(translation) { 24 | return { 25 | l: function(key) { 26 | if (translation[key]) return translation[key]; 27 | return '(no translation for ' + key + ')'; 28 | } 29 | }; 30 | } 31 | ]). 32 | 33 | // Running code 34 | factory('run', ['$window', 'editor', 35 | function(win, editor) { 36 | var writeInterceptor = function(writer, done) { 37 | return function(write) { 38 | if (write.Kind == 'stderr') { 39 | var lines = write.Body.split('\n'); 40 | for (var i in lines) { 41 | var match = lines[i].match(/.*\.go:([0-9]+): ([^\n]*)/); 42 | if (match !== null) { 43 | editor.highlight(match[1], match[2]); 44 | } 45 | } 46 | } 47 | writer(write); 48 | if (write.Kind == 'end') done(); 49 | }; 50 | }; 51 | return function(code, output, options, done) { 52 | // PlaygroundOutput is defined in playground.js which is prepended 53 | // to the generated script.js in gotour/tour.go. 54 | // The next line removes the jshint warning. 55 | // global PlaygroundOutput 56 | return win.transport.Run(code, writeInterceptor(PlaygroundOutput(output), done), options); 57 | }; 58 | } 59 | ]). 60 | 61 | // Formatting code 62 | factory('fmt', ['$http', 63 | function($http) { 64 | return function(body) { 65 | var params = $.param({ 66 | 'body': body 67 | }); 68 | var headers = { 69 | 'Content-Type': 'application/x-www-form-urlencoded' 70 | }; 71 | return $http.post('/fmt', params, { 72 | headers: headers 73 | }); 74 | }; 75 | } 76 | ]). 77 | 78 | // Local storage, persistent to page refreshing. 79 | factory('storage', ['$window', 80 | function(win) { 81 | try { 82 | // This will raise an exception if cookies are disabled. 83 | win.localStorage = win.localStorage; 84 | return { 85 | get: function(key) { 86 | return win.localStorage.getItem(key); 87 | }, 88 | set: function(key, val) { 89 | win.localStorage.setItem(key, val); 90 | } 91 | }; 92 | } catch (e) { 93 | return { 94 | get: function() { 95 | return null; 96 | }, 97 | set: function() {} 98 | }; 99 | } 100 | } 101 | ]). 102 | 103 | // Editor context service, kept through the whole app. 104 | factory('editor', ['$window', 'storage', 105 | function(win, storage) { 106 | var ctx = { 107 | syntax: storage.get('syntax') === 'true', 108 | toggleSyntax: function() { 109 | ctx.syntax = !ctx.syntax; 110 | storage.set('syntax', ctx.syntax); 111 | ctx.paint(); 112 | }, 113 | paint: function() { 114 | var mode = ctx.syntax && 'text/x-go' || 'text/x-go-comment'; 115 | // Wait for codemirror to start. 116 | var set = function() { 117 | if ($('.CodeMirror').length > 0) { 118 | var cm = $('.CodeMirror')[0].CodeMirror; 119 | if (cm.getOption('mode') == mode) { 120 | cm.refresh(); 121 | return; 122 | } 123 | cm.setOption('mode', mode); 124 | } 125 | win.setTimeout(set, 10); 126 | }; 127 | set(); 128 | }, 129 | highlight: function(line, message) { 130 | $('.CodeMirror-code > div:nth-child(' + line + ')') 131 | .addClass('line-error').attr('title', message); 132 | }, 133 | onChange: function() { 134 | $('.line-error').removeClass('line-error').attr('title', null); 135 | } 136 | }; 137 | // Set in the window so the onChange function in the codemirror config 138 | // can call it. 139 | win.codeChanged = ctx.onChange; 140 | return ctx; 141 | } 142 | ]). 143 | 144 | // Table of contents management and navigation 145 | factory('toc', ['$http', '$q', '$log', 'tableOfContents', 'storage', 146 | function($http, $q, $log, tableOfContents, storage) { 147 | var modules = tableOfContents; 148 | 149 | var lessons = {}; 150 | 151 | var prevLesson = function(id) { 152 | var mod = lessons[id].module; 153 | var idx = mod.lessons.indexOf(id); 154 | if (idx < 0) return ''; 155 | if (idx > 0) return mod.lessons[idx - 1]; 156 | 157 | idx = modules.indexOf(mod); 158 | if (idx <= 0) return ''; 159 | mod = modules[idx - 1]; 160 | return mod.lessons[mod.lessons.length - 1]; 161 | }; 162 | 163 | var nextLesson = function(id) { 164 | var mod = lessons[id].module; 165 | var idx = mod.lessons.indexOf(id); 166 | if (idx < 0) return ''; 167 | if (idx + 1 < mod.lessons.length) return mod.lessons[idx + 1]; 168 | 169 | idx = modules.indexOf(mod); 170 | if (idx < 0 || modules.length <= idx + 1) return ''; 171 | mod = modules[idx + 1]; 172 | return mod.lessons[0]; 173 | }; 174 | 175 | $http.get('/lesson/').then( 176 | function(data) { 177 | lessons = data.data; 178 | for (var m = 0; m < modules.length; m++) { 179 | var module = modules[m]; 180 | module.lesson = {}; 181 | for (var l = 0; l < modules[m].lessons.length; l++) { 182 | var lessonName = module.lessons[l]; 183 | var lesson = lessons[lessonName]; 184 | lesson.module = module; 185 | module.lesson[lessonName] = lesson; 186 | 187 | // replace file contents with locally stored copies. 188 | for (var p = 0; p < lesson.Pages.length; p++) { 189 | var page = lesson.Pages[p]; 190 | for (var f = 0; f < page.Files.length; f++) { 191 | page.Files[f].OrigContent = page.Files[f].Content; 192 | var val = storage.get(page.Files[f].Hash); 193 | if (val !== null) { 194 | page.Files[f].Content = val; 195 | } 196 | } 197 | } 198 | } 199 | } 200 | moduleQ.resolve(modules); 201 | lessonQ.resolve(lessons); 202 | }, 203 | function(error) { 204 | $log.error('error loading lessons : ', error); 205 | moduleQ.reject(error); 206 | lessonQ.reject(error); 207 | } 208 | ); 209 | 210 | var moduleQ = $q.defer(); 211 | var lessonQ = $q.defer(); 212 | 213 | return { 214 | modules: moduleQ.promise, 215 | lessons: lessonQ.promise, 216 | prevLesson: prevLesson, 217 | nextLesson: nextLesson 218 | }; 219 | } 220 | ]); 221 | -------------------------------------------------------------------------------- /static/js/values.js: -------------------------------------------------------------------------------- 1 | /* Copyright 2012 The Go Authors. All rights reserved. 2 | * Use of this source code is governed by a BSD-style 3 | * license that can be found in the LICENSE file. 4 | */ 5 | 'use strict'; 6 | 7 | angular.module('tour.values', []). 8 | 9 | // List of modules with description and lessons in it. 10 | value('tableOfContents', [{ 11 | 'id': 'mechanics', 12 | 'title': 'Go turu kullanımı', 13 | 'description': '

Go programlama dili turuna hoşgeldiniz. Turumuz, dilin en önemli özelliklerini kapsayan üç ana bölümden oluşuyor:

', 14 | 'lessons': ['welcome'] 15 | }, { 16 | 'id': 'basics', 17 | 'title': 'Temel kavramlar', 18 | 'description': '

Başlangıç olarak, dilin temellerini öğrenin.

Değişken tanımlama, fonksiyon çağırma ve diğer konulara geçmeden önce bilmeniz gereken herşey.

', 19 | 'lessons': ['basics', 'flowcontrol', 'moretypes'] 20 | }, { 21 | 'id': 'methods', 22 | 'title': 'Metodlar ve arayüzler', 23 | 'description': '

Türlere metod tanımlamayı, arayüz bildirmeyi ve bunların hepsini nasıl bir arada kullanacağınızı öğrenin.

', 24 | 'lessons': ['methods'] 25 | }, { 26 | 'id': 'concurrency', 27 | 'title': 'Eşzamanlılık', 28 | 'description': '

Go, eşzamanlılık özelliklerini dilin temel bir parçası olarak sunar.

Bu bölüm, go rutinlerin ve kanalların eşzamanlılık desenlerini gerçeklemede nasıl kullanıldığı anlatır.

', 29 | 'lessons': ['concurrency'] 30 | }]). 31 | 32 | // translation 33 | value('translation', { 34 | 'off': 'kapalı', 35 | 'on': 'açık', 36 | 'syntax': 'Sözdizimi Renklendirmesi', 37 | 'lineno': 'Satır Numaraları', 38 | 'reset': 'Slaytı Sıfırla', 39 | 'format': 'Kaynak Kodu Biçimle', 40 | 'kill': 'Programı Öldür', 41 | 'run': 'Çalıştır', 42 | 'compile': 'Derle ve Çalıştır', 43 | 'more': 'Seçenekler', 44 | 'toc': 'İçindekiler', 45 | 'prev': 'Geri', 46 | 'next': 'İleri', 47 | 'waiting': 'Sunucu bekleniyor...', 48 | 'errcomm': 'Sunucu iletişiminde hata.', 49 | 'submit-feedback': 'Bu sayfa hakkında geri bildirimde bulun', 50 | 51 | // GitHub issue template: update repo and messaging when translating. 52 | 'github-repo': 'github.com/golang-tr/tour', 53 | 'issue-title': 'tur: [KISA AÇIKLAMA İLE DEĞİŞTİRİN]', 54 | 'issue-message': 'Yukarıdaki başlığı sorunu tarif edecek şekilde değiştirin ve geri bildiriminizi (gerekiyorsa ilgili kodla birlikte) buraya ekleyin', 55 | 'context': 'Bağlam', 56 | }). 57 | 58 | // Config for codemirror plugin 59 | value('ui.config', { 60 | codemirror: { 61 | mode: 'text/x-go', 62 | matchBrackets: true, 63 | lineNumbers: true, 64 | autofocus: true, 65 | indentWithTabs: true, 66 | indentUnit: 4, 67 | tabSize: 4, 68 | lineWrapping: true, 69 | extraKeys: { 70 | 'Shift-Enter': function() { 71 | $('#run').click(); 72 | }, 73 | 'Ctrl-Enter': function() { 74 | $('#format').click(); 75 | }, 76 | 'PageDown': function() { 77 | return false; 78 | }, 79 | 'PageUp': function() { 80 | return false; 81 | }, 82 | }, 83 | // TODO: is there a better way to do this? 84 | // AngularJS values can't depend on factories. 85 | onChange: function() { 86 | if (window.codeChanged !== null) window.codeChanged(); 87 | } 88 | } 89 | }). 90 | 91 | // mapping from the old paths (#42) to the new organization. 92 | // The values have been generated with the map.sh script in the tools directory. 93 | value('mapping', { 94 | '#1': '/welcome/1', // Hello, 世界 95 | '#2': '/welcome/2', // Go local 96 | '#3': '/basics/1', // Packages 97 | '#4': '/basics/2', // Imports 98 | '#5': '/basics/3', // Exported names 99 | '#6': '/basics/4', // Functions 100 | '#7': '/basics/5', // Functions continued 101 | '#8': '/basics/6', // Multiple results 102 | '#9': undefined, // Named results 103 | '#10': '/basics/8', // Variables 104 | '#11': '/basics/9', // Variables with initializers 105 | '#12': '/basics/10', // Short variable declarations 106 | '#13': '/basics/11', // Basic types 107 | '#14': '/basics/13', // Type conversions 108 | '#15': '/basics/15', // Constants 109 | '#16': '/basics/16', // Numeric Constants 110 | '#17': '/flowcontrol/1', // For 111 | '#18': '/flowcontrol/2', // For continued 112 | '#19': '/flowcontrol/3', // For is Go's "while" 113 | '#20': '/flowcontrol/4', // Forever 114 | '#21': '/flowcontrol/5', // If 115 | '#22': '/flowcontrol/6', // If with a short statement 116 | '#23': '/flowcontrol/7', // If and else 117 | '#24': '/flowcontrol/8', // Exercise: Loops and Functions 118 | '#25': '/moretypes/2', // Structs 119 | '#26': '/moretypes/3', // Struct Fields 120 | '#27': '/moretypes/1', // Pointers 121 | '#28': '/moretypes/5', // Struct Literals 122 | '#29': undefined, // The new function 123 | '#30': '/moretypes/6', // Arrays 124 | '#31': '/moretypes/7', // Slices 125 | '#32': '/moretypes/8', // Slicing slices 126 | '#33': '/moretypes/9', // Making slices 127 | '#34': '/moretypes/10', // Nil slices 128 | '#35': '/moretypes/12', // Range 129 | '#36': '/moretypes/13', // Range continued 130 | '#37': '/moretypes/14', // Exercise: Slices 131 | '#38': '/moretypes/15', // Maps 132 | '#39': '/moretypes/16', // Map literals 133 | '#40': '/moretypes/17', // Map literals continued 134 | '#41': '/moretypes/18', // Mutating Maps 135 | '#42': '/moretypes/19', // Exercise: Maps 136 | '#43': '/moretypes/20', // Function values 137 | '#44': '/moretypes/21', // Function closures 138 | '#45': '/moretypes/22', // Exercise: Fibonacci closure 139 | '#46': '/flowcontrol/9', // Switch 140 | '#47': '/flowcontrol/10', // Switch evaluation order 141 | '#48': '/flowcontrol/11', // Switch with no condition 142 | '#49': undefined, // Advanced Exercise: Complex cube roots 143 | '#50': undefined, // Methods and Interfaces 144 | '#51': '/methods/1', // Methods 145 | '#52': '/methods/2', // Methods continued 146 | '#53': '/methods/3', // Methods with pointer receivers 147 | '#54': '/methods/4', // Interfaces 148 | '#55': '/methods/5', // Interfaces are satisfied implicitly 149 | '#56': '/methods/8', // Errors 150 | '#57': '/methods/9', // Exercise: Errors 151 | '#58': '/methods/13', // Web servers 152 | '#59': '/methods/14', // Exercise: HTTP Handlers 153 | '#60': '/methods/15', // Images 154 | '#61': '/methods/16', // Exercise: Images 155 | '#62': undefined, // Exercise: Rot13 Reader 156 | '#63': undefined, // Concurrency 157 | '#64': '/concurrency/1', // Goroutines 158 | '#65': '/concurrency/2', // Channels 159 | '#66': '/concurrency/3', // Buffered Channels 160 | '#67': '/concurrency/4', // Range and Close 161 | '#68': '/concurrency/5', // Select 162 | '#69': '/concurrency/6', // Default Selection 163 | '#70': '/concurrency/7', // Exercise: Equivalent Binary Trees 164 | '#71': '/concurrency/8', // Exercise: Equivalent Binary Trees 165 | '#72': '/concurrency/9', // Exercise: Web Crawler 166 | '#73': '/concurrency/10', // Where to Go from here... 167 | }); 168 | -------------------------------------------------------------------------------- /static/lib/codemirror/AUTHORS: -------------------------------------------------------------------------------- 1 | List of CodeMirror contributors. Updated before every release. 2 | 3 | 4r2r 4 | Aaron Brooks 5 | Adam King 6 | adanlobato 7 | Adán Lobato 8 | aeroson 9 | Ahmad Amireh 10 | Ahmad M. Zawawi 11 | ahoward 12 | Akeksandr Motsjonov 13 | Albert Xing 14 | Alexander Pavlov 15 | Alexander Schepanovski 16 | alexey-k 17 | Alex Piggott 18 | Amy 19 | Ananya Sen 20 | Andre von Houck 21 | Andrey Lushnikov 22 | Andy Kimball 23 | Andy Li 24 | angelozerr 25 | angelo.zerr@gmail.com 26 | Ankit Ahuja 27 | Ansel Santosa 28 | Anthony Grimes 29 | areos 30 | Atul Bhouraskar 31 | Aurelian Oancea 32 | Bastian Müller 33 | benbro 34 | Benjamin DeCoste 35 | Ben Keen 36 | boomyjee 37 | borawjm 38 | Brandon Frohs 39 | Brian Sletten 40 | Bruce Mitchener 41 | Chandra Sekhar Pydi 42 | Charles Skelton 43 | Chris Coyier 44 | Chris Granger 45 | Chris Morgan 46 | Christopher Brown 47 | CodeAnimal 48 | ComFreek 49 | dagsta 50 | Dan Heberden 51 | Daniel, Dao Quang Minh 52 | Daniel Faust 53 | Daniel Huigens 54 | Daniel Neel 55 | Daniel Parnell 56 | Danny Yoo 57 | David Mignot 58 | David Pathakjee 59 | deebugger 60 | Deep Thought 61 | Dominator008 62 | Domizio Demichelis 63 | Drew Bratcher 64 | Drew Hintz 65 | Drew Khoury 66 | Dror BG 67 | duralog 68 | edsharp 69 | ekhaled 70 | Eric Allam 71 | eustas 72 | Fauntleroy 73 | fbuchinger 74 | feizhang365 75 | Felipe Lalanne 76 | Felix Raab 77 | Filip Noetzel 78 | flack 79 | Ford_Lawnmower 80 | Gabriel Nahmias 81 | galambalazs 82 | Gautam Mehta 83 | Glenn Ruehle 84 | Golevka 85 | Gordon Smith 86 | greengiant 87 | Guillaume Massé 88 | Hans Engel 89 | Hardest 90 | Hasan Karahan 91 | Hocdoc 92 | Ian Beck 93 | Ian Wehrman 94 | Ian Wetherbee 95 | Ice White 96 | ICHIKAWA, Yuji 97 | Ingo Richter 98 | Irakli Gozalishvili 99 | Ivan Kurnosov 100 | Jacob Lee 101 | Jakub Vrana 102 | James Campos 103 | James Thorne 104 | Jamie Hill 105 | Jan Jongboom 106 | jankeromnes 107 | Jan Keromnes 108 | Jan T. Sott 109 | Jason 110 | Jason Grout 111 | Jason Johnston 112 | Jason San Jose 113 | Jason Siefken 114 | Jean Boussier 115 | jeffkenton 116 | Jeff Pickhardt 117 | jem (graphite) 118 | Jochen Berger 119 | John Connor 120 | John Lees-Miller 121 | John Snelson 122 | jongalloway 123 | Joost-Wim Boekesteijn 124 | Joseph Pecoraro 125 | Joshua Newman 126 | jots 127 | Juan Benavides Romero 128 | Jucovschi Constantin 129 | jwallers@gmail.com 130 | kaniga 131 | Ken Newman 132 | Ken Rockot 133 | Kevin Sawicki 134 | Klaus Silveira 135 | Koh Zi Han, Cliff 136 | komakino 137 | Konstantin Lopuhin 138 | koops 139 | ks-ifware 140 | Lanny 141 | leaf corcoran 142 | Leonya Khachaturov 143 | Liam Newman 144 | List of contributors. Updated before every release. 145 | LM 146 | Lorenzo Stoakes 147 | lynschinzer 148 | Maksim Lin 149 | Maksym Taran 150 | Marat Dreizin 151 | Marco Aurélio 152 | Marijn Haverbeke 153 | Mario Pietsch 154 | Mark Lentczner 155 | Mason Malone 156 | Mateusz Paprocki 157 | mats cronqvist 158 | Matthew Beale 159 | Matthias BUSSONNIER 160 | Matt McDonald 161 | Matt Pass 162 | Matt Sacks 163 | Maximilian Hils 164 | Max Kirsch 165 | mbarkhau 166 | Metatheos 167 | Micah Dubinko 168 | Michael Lehenbauer 169 | Michael Zhou 170 | Mighty Guava 171 | Miguel Castillo 172 | Mike 173 | Mike Brevoort 174 | Mike Diaz 175 | Mike Ivanov 176 | Mike Kadin 177 | MinRK 178 | misfo 179 | mps 180 | Narciso Jaramillo 181 | Nathan Williams 182 | nerbert 183 | nguillaumin 184 | Niels van Groningen 185 | Nikita Beloglazov 186 | Nikita Vasilyev 187 | nlwillia 188 | pablo 189 | Page 190 | Patrick Strawderman 191 | Paul Garvin 192 | Paul Ivanov 193 | Pavel Feldman 194 | Paweł Bartkiewicz 195 | peteguhl 196 | peterkroon 197 | Peter Kroon 198 | prasanthj 199 | Prasanth J 200 | Rahul 201 | Randy Edmunds 202 | Richard Z.H. Wang 203 | robertop23 204 | Robert Plummer 205 | Ruslan Osmanov 206 | sabaca 207 | Samuel Ainsworth 208 | sandeepshetty 209 | santec 210 | Sascha Peilicke 211 | satchmorun 212 | sathyamoorthi 213 | SCLINIC\jdecker 214 | shaund 215 | shaun gilchrist 216 | Shmuel Englard 217 | sonson 218 | spastorelli 219 | Stas Kobzar 220 | Stefan Borsje 221 | Steffen Beyer 222 | Steve O'Hara 223 | Tarmil 224 | tfjgeorge 225 | Thaddee Tyl 226 | think 227 | Thomas Dvornik 228 | Thomas Schmid 229 | Tim Baumann 230 | Timothy Farrell 231 | Timothy Hatcher 232 | Tomas Varaneckas 233 | Tom Erik Støwer 234 | Tom MacWright 235 | Tony Jian 236 | Vestimir Markov 237 | vf 238 | Volker Mische 239 | William Jamieson 240 | Wojtek Ptak 241 | Xavier Mendez 242 | Yunchi Luo 243 | Yuvi Panda 244 | Zachary Dremann 245 | -------------------------------------------------------------------------------- /static/lib/codemirror/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 by Marijn Haverbeke and others 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | Please note that some subdirectories of the CodeMirror distribution 22 | include their own LICENSE files, and are released under different 23 | licences. 24 | -------------------------------------------------------------------------------- /static/lib/codemirror/README.md: -------------------------------------------------------------------------------- 1 | # CodeMirror 2 | [![Build Status](https://secure.travis-ci.org/marijnh/CodeMirror.png?branch=master)](http://travis-ci.org/marijnh/CodeMirror) 3 | [![NPM version](https://badge.fury.io/js/codemirror.png)](http://badge.fury.io/js/codemirror) 4 | 5 | CodeMirror is a JavaScript component that provides a code editor in 6 | the browser. When a mode is available for the language you are coding 7 | in, it will color your code, and optionally help with indentation. 8 | 9 | The project page is http://codemirror.net 10 | The manual is at http://codemirror.net/doc/manual.html 11 | The contributing guidelines are in [CONTRIBUTING.md](https://github.com/marijnh/CodeMirror/blob/master/CONTRIBUTING.md) 12 | -------------------------------------------------------------------------------- /static/lib/codemirror/lib/codemirror.css: -------------------------------------------------------------------------------- 1 | /* BASICS */ 2 | 3 | .CodeMirror { 4 | /* Set height, width, borders, and global font properties here */ 5 | font-family: monospace; 6 | height: 300px; 7 | } 8 | .CodeMirror-scroll { 9 | /* Set scrolling behaviour here */ 10 | overflow: auto; 11 | } 12 | 13 | /* PADDING */ 14 | 15 | .CodeMirror-lines { 16 | padding: 4px 0; /* Vertical padding around content */ 17 | } 18 | .CodeMirror pre { 19 | padding: 0 4px; /* Horizontal padding of content */ 20 | } 21 | 22 | .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 23 | background-color: white; /* The little square between H and V scrollbars */ 24 | } 25 | 26 | /* GUTTER */ 27 | 28 | .CodeMirror-gutters { 29 | border-right: 1px solid #ddd; 30 | background-color: #f7f7f7; 31 | white-space: nowrap; 32 | } 33 | .CodeMirror-linenumbers {} 34 | .CodeMirror-linenumber { 35 | padding: 0 3px 0 5px; 36 | min-width: 20px; 37 | text-align: right; 38 | color: #999; 39 | } 40 | 41 | /* CURSOR */ 42 | 43 | .CodeMirror div.CodeMirror-cursor { 44 | border-left: 1px solid black; 45 | z-index: 3; 46 | } 47 | /* Shown when moving in bi-directional text */ 48 | .CodeMirror div.CodeMirror-secondarycursor { 49 | border-left: 1px solid silver; 50 | } 51 | .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { 52 | width: auto; 53 | border: 0; 54 | background: #7e7; 55 | z-index: 1; 56 | } 57 | /* Can style cursor different in overwrite (non-insert) mode */ 58 | .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {} 59 | 60 | .cm-tab { display: inline-block; } 61 | 62 | /* DEFAULT THEME */ 63 | 64 | .cm-s-default .cm-keyword {color: #708;} 65 | .cm-s-default .cm-atom {color: #219;} 66 | .cm-s-default .cm-number {color: #164;} 67 | .cm-s-default .cm-def {color: #00f;} 68 | .cm-s-default .cm-variable {color: black;} 69 | .cm-s-default .cm-variable-2 {color: #05a;} 70 | .cm-s-default .cm-variable-3 {color: #085;} 71 | .cm-s-default .cm-property {color: black;} 72 | .cm-s-default .cm-operator {color: black;} 73 | .cm-s-default .cm-comment {color: #a50;} 74 | .cm-s-default .cm-string {color: #a11;} 75 | .cm-s-default .cm-string-2 {color: #f50;} 76 | .cm-s-default .cm-meta {color: #555;} 77 | .cm-s-default .cm-error {color: #f00;} 78 | .cm-s-default .cm-qualifier {color: #555;} 79 | .cm-s-default .cm-builtin {color: #30a;} 80 | .cm-s-default .cm-bracket {color: #997;} 81 | .cm-s-default .cm-tag {color: #170;} 82 | .cm-s-default .cm-attribute {color: #00c;} 83 | .cm-s-default .cm-header {color: blue;} 84 | .cm-s-default .cm-quote {color: #090;} 85 | .cm-s-default .cm-hr {color: #999;} 86 | .cm-s-default .cm-link {color: #00c;} 87 | 88 | .cm-negative {color: #d44;} 89 | .cm-positive {color: #292;} 90 | .cm-header, .cm-strong {font-weight: bold;} 91 | .cm-em {font-style: italic;} 92 | .cm-link {text-decoration: underline;} 93 | 94 | .cm-invalidchar {color: #f00;} 95 | 96 | div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} 97 | div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} 98 | .CodeMirror-activeline-background {background: #e8f2ff;} 99 | 100 | /* STOP */ 101 | 102 | /* The rest of this file contains styles related to the mechanics of 103 | the editor. You probably shouldn't touch them. */ 104 | 105 | .CodeMirror { 106 | line-height: 1; 107 | position: relative; 108 | overflow: hidden; 109 | background: white; 110 | color: black; 111 | } 112 | 113 | .CodeMirror-scroll { 114 | /* 30px is the magic margin used to hide the element's real scrollbars */ 115 | /* See overflow: hidden in .CodeMirror */ 116 | margin-bottom: -30px; margin-right: -30px; 117 | padding-bottom: 30px; padding-right: 30px; 118 | height: 100%; 119 | outline: none; /* Prevent dragging from highlighting the element */ 120 | position: relative; 121 | } 122 | .CodeMirror-sizer { 123 | position: relative; 124 | } 125 | 126 | /* The fake, visible scrollbars. Used to force redraw during scrolling 127 | before actuall scrolling happens, thus preventing shaking and 128 | flickering artifacts. */ 129 | .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { 130 | position: absolute; 131 | z-index: 6; 132 | display: none; 133 | } 134 | .CodeMirror-vscrollbar { 135 | right: 0; top: 0; 136 | overflow-x: hidden; 137 | overflow-y: scroll; 138 | } 139 | .CodeMirror-hscrollbar { 140 | bottom: 0; left: 0; 141 | overflow-y: hidden; 142 | overflow-x: scroll; 143 | } 144 | .CodeMirror-scrollbar-filler { 145 | right: 0; bottom: 0; 146 | } 147 | .CodeMirror-gutter-filler { 148 | left: 0; bottom: 0; 149 | } 150 | 151 | .CodeMirror-gutters { 152 | position: absolute; left: 0; top: 0; 153 | padding-bottom: 30px; 154 | z-index: 3; 155 | } 156 | .CodeMirror-gutter { 157 | white-space: normal; 158 | height: 100%; 159 | padding-bottom: 30px; 160 | margin-bottom: -32px; 161 | display: inline-block; 162 | /* Hack to make IE7 behave */ 163 | *zoom:1; 164 | *display:inline; 165 | } 166 | .CodeMirror-gutter-elt { 167 | position: absolute; 168 | cursor: default; 169 | z-index: 4; 170 | } 171 | 172 | .CodeMirror-lines { 173 | cursor: text; 174 | } 175 | .CodeMirror pre { 176 | /* Reset some styles that the rest of the page might have set */ 177 | -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; 178 | border-width: 0; 179 | background: transparent; 180 | font-family: inherit; 181 | font-size: inherit; 182 | margin: 0; 183 | white-space: pre; 184 | word-wrap: normal; 185 | line-height: inherit; 186 | color: inherit; 187 | z-index: 2; 188 | position: relative; 189 | overflow: visible; 190 | } 191 | .CodeMirror-wrap pre { 192 | word-wrap: break-word; 193 | white-space: pre-wrap; 194 | word-break: normal; 195 | } 196 | .CodeMirror-code pre { 197 | border-right: 30px solid transparent; 198 | width: -webkit-fit-content; 199 | width: -moz-fit-content; 200 | width: fit-content; 201 | } 202 | .CodeMirror-wrap .CodeMirror-code pre { 203 | border-right: none; 204 | width: auto; 205 | } 206 | .CodeMirror-linebackground { 207 | position: absolute; 208 | left: 0; right: 0; top: 0; bottom: 0; 209 | z-index: 0; 210 | } 211 | 212 | .CodeMirror-linewidget { 213 | position: relative; 214 | z-index: 2; 215 | overflow: auto; 216 | } 217 | 218 | .CodeMirror-widget { 219 | } 220 | 221 | .CodeMirror-wrap .CodeMirror-scroll { 222 | overflow-x: hidden; 223 | } 224 | 225 | .CodeMirror-measure { 226 | position: absolute; 227 | width: 100%; height: 0px; 228 | overflow: hidden; 229 | visibility: hidden; 230 | } 231 | .CodeMirror-measure pre { position: static; } 232 | 233 | .CodeMirror div.CodeMirror-cursor { 234 | position: absolute; 235 | visibility: hidden; 236 | border-right: none; 237 | width: 0; 238 | } 239 | .CodeMirror-focused div.CodeMirror-cursor { 240 | visibility: visible; 241 | } 242 | 243 | .CodeMirror-selected { background: #d9d9d9; } 244 | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } 245 | 246 | .cm-searching { 247 | background: #ffa; 248 | background: rgba(255, 255, 0, .4); 249 | } 250 | 251 | /* IE7 hack to prevent it from returning funny offsetTops on the spans */ 252 | .CodeMirror span { *vertical-align: text-bottom; } 253 | 254 | @media print { 255 | /* Hide the cursor when printing */ 256 | .CodeMirror div.CodeMirror-cursor { 257 | visibility: hidden; 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /static/lib/codemirror/mode/go/go.js: -------------------------------------------------------------------------------- 1 | function goMode(commentsOnly) { 2 | return function(config) { 3 | var indentUnit = config.indentUnit; 4 | 5 | var keywords = { 6 | "break":true, "case":true, "chan":true, "const":true, "continue":true, 7 | "default":true, "defer":true, "else":true, "fallthrough":true, "for":true, 8 | "func":true, "go":true, "goto":true, "if":true, "import":true, 9 | "interface":true, "map":true, "package":true, "range":true, "return":true, 10 | "select":true, "struct":true, "switch":true, "type":true, "var":true, 11 | "bool":true, "byte":true, "complex64":true, "complex128":true, "error":true, 12 | "float32":true, "float64":true, "int8":true, "int16":true, "int32":true, 13 | "int64":true, "rune":true, "string":true, "uint8":true, "uint16":true, "uint32":true, 14 | "uint64":true, "int":true, "uint":true, "uintptr":true 15 | }; 16 | 17 | var atoms = { 18 | "true":true, "false":true, "iota":true, "nil":true, "append":true, 19 | "cap":true, "close":true, "complex":true, "copy":true, "delete":true, "imag":true, 20 | "len":true, "make":true, "new":true, "panic":true, "print":true, 21 | "println":true, "real":true, "recover":true 22 | }; 23 | 24 | var isOperatorChar = /[+\-*&^%:=<>!|\/]/; 25 | 26 | var curPunc; 27 | 28 | function tokenBase(stream, state) { 29 | var ch = stream.next(); 30 | if (ch == '"' || ch == "'" || ch == "`") { 31 | state.tokenize = tokenString(ch); 32 | return state.tokenize(stream, state); 33 | } 34 | if (/[\d\.]/.test(ch)) { 35 | if (ch == ".") { 36 | stream.match(/^[0-9]+([eE][\-+]?[0-9]+)?/); 37 | } else if (ch == "0") { 38 | stream.match(/^[xX][0-9a-fA-F]+/) || stream.match(/^0[0-7]+/); 39 | } else { 40 | stream.match(/^[0-9]*\.?[0-9]*([eE][\-+]?[0-9]+)?/); 41 | } 42 | return "number"; 43 | } 44 | if (/[\[\]{}\(\),;\:\.]/.test(ch)) { 45 | curPunc = ch; 46 | return null; 47 | } 48 | if (ch == "/") { 49 | if (stream.eat("*")) { 50 | state.tokenize = tokenComment; 51 | return tokenComment(stream, state); 52 | } 53 | if (stream.eat("/")) { 54 | stream.skipToEnd(); 55 | return "comment"; 56 | } 57 | } 58 | if (isOperatorChar.test(ch)) { 59 | stream.eatWhile(isOperatorChar); 60 | return "operator"; 61 | } 62 | stream.eatWhile(/[\w\$_]/); 63 | var cur = stream.current(); 64 | if (keywords.propertyIsEnumerable(cur)) { 65 | if (cur == "case" || cur == "default") curPunc = "case"; 66 | return "keyword"; 67 | } 68 | if (atoms.propertyIsEnumerable(cur)) return "atom"; 69 | return "variable"; 70 | } 71 | 72 | function tokenString(quote) { 73 | return function(stream, state) { 74 | var escaped = false, 75 | next, end = false; 76 | while ((next = stream.next()) != null) { 77 | if (next == quote && !escaped) { 78 | end = true; 79 | break; 80 | } 81 | escaped = !escaped && next == "\\"; 82 | } 83 | if (end || !(escaped || quote == "`")) 84 | state.tokenize = tokenBase; 85 | return "string"; 86 | }; 87 | } 88 | 89 | function tokenComment(stream, state) { 90 | var maybeEnd = false, 91 | ch; 92 | while (ch = stream.next()) { 93 | if (ch == "/" && maybeEnd) { 94 | state.tokenize = tokenBase; 95 | break; 96 | } 97 | maybeEnd = (ch == "*"); 98 | } 99 | return "comment"; 100 | } 101 | 102 | function Context(indented, column, type, align, prev) { 103 | this.indented = indented; 104 | this.column = column; 105 | this.type = type; 106 | this.align = align; 107 | this.prev = prev; 108 | } 109 | 110 | function pushContext(state, col, type) { 111 | return state.context = new Context(state.indented, col, type, null, state.context); 112 | } 113 | 114 | function popContext(state) { 115 | var t = state.context.type; 116 | if (t == ")" || t == "]" || t == "}") 117 | state.indented = state.context.indented; 118 | return state.context = state.context.prev; 119 | } 120 | 121 | // Interface 122 | 123 | return { 124 | startState: function(basecolumn) { 125 | return { 126 | tokenize: null, 127 | context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), 128 | indented: 0, 129 | startOfLine: true 130 | }; 131 | }, 132 | 133 | token: function(stream, state) { 134 | var ctx = state.context; 135 | if (stream.sol()) { 136 | if (ctx.align == null) ctx.align = false; 137 | state.indented = stream.indentation(); 138 | state.startOfLine = true; 139 | if (ctx.type == "case") ctx.type = "}"; 140 | } 141 | if (stream.eatSpace()) return null; 142 | curPunc = null; 143 | var style = (state.tokenize || tokenBase)(stream, state); 144 | if (style == "comment") return style; 145 | if (ctx.align == null) ctx.align = true; 146 | 147 | if (curPunc == "{") pushContext(state, stream.column(), "}"); 148 | else if (curPunc == "[") pushContext(state, stream.column(), "]"); 149 | else if (curPunc == "(") pushContext(state, stream.column(), ")"); 150 | else if (curPunc == "case") ctx.type = "case"; 151 | else if (curPunc == "}" && ctx.type == "}") ctx = popContext(state); 152 | else if (curPunc == ctx.type) popContext(state); 153 | state.startOfLine = false; 154 | if (commentsOnly) return ""; 155 | return style; 156 | }, 157 | 158 | indent: function(state, textAfter) { 159 | if (state.tokenize != tokenBase && state.tokenize != null) return 0; 160 | var ctx = state.context, 161 | firstChar = textAfter && textAfter.charAt(0); 162 | if (ctx.type == "case" && /^(?:case|default)\b/.test(textAfter)) { 163 | state.context.type = "}"; 164 | return ctx.indented; 165 | } 166 | var closing = firstChar == ctx.type; 167 | if (ctx.align) return ctx.column + (closing ? 0 : 1); 168 | else return ctx.indented + (closing ? 0 : indentUnit); 169 | }, 170 | 171 | electricChars: "{}:", 172 | blockCommentStart: "/*", 173 | blockCommentEnd: "*/", 174 | lineComment: "//" 175 | }; 176 | } 177 | } 178 | 179 | CodeMirror.defineMode("go", goMode(false)); 180 | CodeMirror.defineMIME("text/x-go", "go"); 181 | 182 | CodeMirror.defineMode("goComments", goMode(true)); 183 | CodeMirror.defineMIME("text/x-go-comments", "goComments"); 184 | -------------------------------------------------------------------------------- /static/partials/editor.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 | 8 |
9 | < 10 | {{curPage}}/{{toc.lessons[lessonId].Pages.length}} 11 | > 12 |
13 |
14 |
15 | 16 |
17 |
18 | {{f.Name}} 19 | Renklendirme 20 |
21 | 22 |
23 | 24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 | 32 |
33 | 34 |
35 |
36 | 37 |
38 | Çalıştır 39 | Sonlandır 40 | Biçimle 41 | Sıfırla 42 |
43 | 44 |
45 |
46 |
47 |
48 |
49 |
50 | 51 |
52 |
53 | -------------------------------------------------------------------------------- /static/partials/feedback-button.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /static/partials/lesson.html: -------------------------------------------------------------------------------- 1 |
2 | {{title}} 3 |

{{description}}

4 |
5 | -------------------------------------------------------------------------------- /static/partials/list.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 7 | 8 |
9 |

{{m.title}}

10 |
11 | 12 |
13 | {{m.lesson[l].Title}} 14 |

{{m.lesson[l].Description}}

15 |
16 |
17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /static/partials/toc-button.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /static/partials/toc.html: -------------------------------------------------------------------------------- 1 |
2 |
    3 |
  • 4 | {{m.title}} 5 |
      6 |
    • 7 | {{m.lesson[l].Title}} 8 | 13 |
    • 14 |
    15 |
  • 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /template/action.tmpl: -------------------------------------------------------------------------------- 1 | {{/*{ 2 | This is the action template. 3 | It determines how the formatting actions are rendered. 4 | */}} 5 | 6 | {{define "section"}} 7 |

{{.Title}}

8 | {{range .Elem}}{{elem $.Template .}}{{end}} 9 | {{end}} 10 | 11 | {{define "list"}} 12 | 17 | {{end}} 18 | 19 | {{define "text"}} 20 | {{if .Pre}} 21 |
{{range .Lines}}{{.}}{{end}}
22 | {{else}} 23 |

24 | {{range $i, $l := .Lines}}{{if $i}}{{template "newline"}} 25 | {{end}}{{style $l}}{{end}} 26 |

27 | {{end}} 28 | {{end}} 29 | 30 | {{define "code"}} 31 | {{if .Play}} 32 | {{/* playable code is not displayed in the slides */}} 33 | {{else}} 34 |
{{.Text}}
35 | {{end}} 36 | {{end}} 37 | 38 | {{define "image"}} 39 | 40 | {{end}} 41 | 42 | {{define "link"}} 43 | 44 | {{end}} 45 | 46 | {{define "html"}}{{.HTML}}{{end}} 47 | 48 | {{define "newline"}} 49 | {{/* No automatic line break. Paragraphs are free-form. */}} 50 | {{end}} 51 | -------------------------------------------------------------------------------- /template/index.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Go Turu 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |
24 | 25 |
26 | 27 | 28 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /tools/map.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2011 The Go Authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | # This code parses mapping.old and finds a correspondance from the old 8 | # urls (e.g. #42) to the corresponding path (e.g. /concurrency/3). 9 | 10 | function findURL { 11 | title="$1" 12 | file=$(grep -l "* $title\$" *.article) 13 | if [[ -z $file ]] 14 | then 15 | echo "undefined" 16 | return 1 17 | fi 18 | titles=$(grep "^* " $file | awk '{print NR, $0}') 19 | page=$(echo "$titles" | grep "* $title\$" | awk '{print $1}') 20 | if [[ $(echo "$page" | wc -l) -gt "1" ]] 21 | then 22 | echo "multiple matches found for $title; find 'CHOOSE BETWEEN' in the output" 1>&2 23 | page="CHOOSE BETWEEN $page" 24 | fi 25 | 26 | page=$(echo $page) 27 | lesson=$(echo "$file" | rev | cut -c 9- | rev) 28 | echo "'/$lesson/$page'" 29 | return 0 30 | } 31 | 32 | mapping=`cat mapping.old` 33 | 34 | pushd ../content 35 | echo "$mapping" | while read page; do 36 | num=$(echo "$page" | awk '{print $1}') 37 | title=$(echo "$page" | sed "s/[0-9]* //") 38 | url=$(findURL "$title") 39 | echo " '#$num': $url, // $title" 40 | done 41 | popd > /dev/null 42 | -------------------------------------------------------------------------------- /tools/mapping.old: -------------------------------------------------------------------------------- 1 | 1 Hello, 世界 2 | 2 Go local 3 | 3 Packages 4 | 4 Imports 5 | 5 Exported names 6 | 6 Functions 7 | 7 Functions continued 8 | 8 Multiple results 9 | 9 Named results 10 | 10 Variables 11 | 11 Variables with initializers 12 | 12 Short variable declarations 13 | 13 Basic types 14 | 14 Type conversions 15 | 15 Constants 16 | 16 Numeric Constants 17 | 17 For 18 | 18 For continued 19 | 19 For is Go's "while" 20 | 20 Forever 21 | 21 If 22 | 22 If with a short statement 23 | 23 If and else 24 | 24 Exercise: Loops and Functions 25 | 25 Structs 26 | 26 Struct Fields 27 | 27 Pointers 28 | 28 Struct Literals 29 | 29 The new function 30 | 30 Arrays 31 | 31 Slices 32 | 32 Slicing slices 33 | 33 Making slices 34 | 34 Nil slices 35 | 35 Range 36 | 36 Range continued 37 | 37 Exercise: Slices 38 | 38 Maps 39 | 39 Map literals 40 | 40 Map literals continued 41 | 41 Mutating Maps 42 | 42 Exercise: Maps 43 | 43 Function values 44 | 44 Function closures 45 | 45 Exercise: Fibonacci closure 46 | 46 Switch 47 | 47 Switch evaluation order 48 | 48 Switch with no condition 49 | 49 Advanced Exercise: Complex cube roots 50 | 50 Methods and Interfaces 51 | 51 Methods 52 | 52 Methods continued 53 | 53 Methods with pointer receivers 54 | 54 Interfaces 55 | 55 Interfaces are satisfied implicitly 56 | 56 Errors 57 | 57 Exercise: Errors 58 | 58 Web servers 59 | 59 Exercise: HTTP Handlers 60 | 60 Images 61 | 61 Exercise: Images 62 | 62 Exercise: Rot13 Reader 63 | 63 Concurrency 64 | 64 Goroutines 65 | 65 Channels 66 | 66 Buffered Channels 67 | 67 Range and Close 68 | 68 Select 69 | 69 Default Selection 70 | 70 Exercise: Equivalent Binary Trees 71 | 71 Exercise: Equivalent Binary Trees 72 | 72 Exercise: Web Crawler 73 | 73 Where to Go from here... 74 | -------------------------------------------------------------------------------- /tree/tree.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tree // import "golang.org/x/tour/tree" 6 | 7 | import ( 8 | "fmt" 9 | "math/rand" 10 | ) 11 | 12 | // A Tree is a binary tree with integer values. 13 | type Tree struct { 14 | Left *Tree 15 | Value int 16 | Right *Tree 17 | } 18 | 19 | // New returns a new, random binary tree holding the values k, 2k, ..., 10k. 20 | func New(k int) *Tree { 21 | var t *Tree 22 | for _, v := range rand.Perm(10) { 23 | t = insert(t, (1+v)*k) 24 | } 25 | return t 26 | } 27 | 28 | func insert(t *Tree, v int) *Tree { 29 | if t == nil { 30 | return &Tree{nil, v, nil} 31 | } 32 | if v < t.Value { 33 | t.Left = insert(t.Left, v) 34 | } else { 35 | t.Right = insert(t.Right, v) 36 | } 37 | return t 38 | } 39 | 40 | func (t *Tree) String() string { 41 | if t == nil { 42 | return "()" 43 | } 44 | s := "" 45 | if t.Left != nil { 46 | s += t.Left.String() + " " 47 | } 48 | s += fmt.Sprint(t.Value) 49 | if t.Right != nil { 50 | s += " " + t.Right.String() 51 | } 52 | return "(" + s + ")" 53 | } 54 | -------------------------------------------------------------------------------- /wc/wc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package wc // import "golang.org/x/tour/wc" 6 | 7 | import "fmt" 8 | 9 | // Test runs a test suite against f. 10 | func Test(f func(string) map[string]int) { 11 | ok := true 12 | for _, c := range testCases { 13 | got := f(c.in) 14 | if len(c.want) != len(got) { 15 | ok = false 16 | } else { 17 | for k := range c.want { 18 | if c.want[k] != got[k] { 19 | ok = false 20 | } 21 | } 22 | } 23 | if !ok { 24 | fmt.Printf("FAIL\n f(%q) =\n %#v\n want:\n %#v", 25 | c.in, got, c.want) 26 | break 27 | } 28 | fmt.Printf("PASS\n f(%q) = \n %#v\n", c.in, got) 29 | } 30 | } 31 | 32 | var testCases = []struct { 33 | in string 34 | want map[string]int 35 | }{ 36 | {"I am learning Go!", map[string]int{ 37 | "I": 1, "am": 1, "learning": 1, "Go!": 1, 38 | }}, 39 | {"The quick brown fox jumped over the lazy dog.", map[string]int{ 40 | "The": 1, "quick": 1, "brown": 1, "fox": 1, "jumped": 1, 41 | "over": 1, "the": 1, "lazy": 1, "dog.": 1, 42 | }}, 43 | {"I ate a donut. Then I ate another donut.", map[string]int{ 44 | "I": 2, "ate": 2, "a": 1, "donut.": 2, "Then": 1, "another": 1, 45 | }}, 46 | {"A man a plan a canal panama.", map[string]int{ 47 | "A": 1, "man": 1, "a": 2, "plan": 1, "canal": 1, "panama.": 1, 48 | }}, 49 | } 50 | --------------------------------------------------------------------------------