├── .gitbook └── assets │ ├── .gitignore │ ├── 2020-11-09_23-38.png │ ├── 2020-11-23_22-30.png │ ├── 2020-11-23_22-38.png │ ├── 3208a2431252c05f682be6a81259afa1.jpeg │ ├── 88iU5v.webp │ ├── DeepinScreenshot_select-area_20191006213837.webp │ ├── DeepinScreenshot_select-area_20200123205023.png │ ├── EvYnc-5VoAEOSTV.jpeg │ ├── LICENSE │ ├── Screen Shot 2022-05-06 at 22.26.18.png │ ├── Screenshot_20201012_130620.png │ ├── ampkullanımı.png │ ├── archlinux-icon.png │ ├── bc.png │ ├── choose │ ├── cobra.png │ ├── compare │ ├── dbbrowser.png │ ├── debian-icon.png │ ├── defaultdebugger1.png │ ├── defaultdebugger2.png │ ├── defaultdebugger3.png │ ├── errorlens.png │ ├── gin-json.png │ ├── gin-param.png │ ├── gin-querystring.png │ ├── github-image.png │ ├── go-gin.png │ ├── go-mod-init.png │ ├── golang-grpc-example.gif │ ├── golang-plugins-all.webp │ ├── golangtrsitelogo.png │ ├── gorm1.png │ ├── heroku-create.png │ ├── heroku-login-success.png │ ├── heroku-login-warning.png │ ├── heroku-login.png │ ├── heroku-push.png │ ├── heroku-site.png │ ├── htmlw.png │ ├── image (1).png │ ├── image (4) (1).png │ ├── image (4).png │ ├── image.png │ ├── instagram-sketched.png │ ├── jskonsole.png │ ├── ken.png │ ├── labels │ ├── linux.png │ ├── linuxmint-icon.png │ ├── livedebug.gif │ ├── macos (1).png │ ├── manjaro-icon.png │ ├── milestones │ ├── mutex.png │ ├── no-vendor.png │ ├── package.png │ ├── pointeronram.png │ ├── pointeryanlış.png │ ├── policy │ ├── prefer.png │ ├── prefer2.png │ ├── protoc-download.png │ ├── rob.jpg │ ├── robert.png │ ├── salca.png │ ├── ssss.png │ ├── statik.png │ ├── str.png │ ├── telegram.png │ ├── thumnailgolang.jpeg.png │ ├── tinygo-logo.png │ ├── twitter.png │ ├── u2XPpO.png │ ├── uEIcZ3.webp │ ├── uber go style guide tr │ ├── ubuntu-icon.png │ ├── viper-logo (1).png │ ├── viper-logo.png │ ├── vt3.png │ ├── windows (1).png │ ├── workflow-rabbitmq.png │ └── youtube.png ├── .github └── FUNDING.yml ├── Golang Örnekler ├── Kullanıcı Bilgi Sistemi │ └── main.go ├── Pisagor Hesaplama │ └── main.go ├── Sayı Tahmin │ └── sayitahmin.go └── Sunucu Oluşturucu │ └── sunucuolusturucu.go ├── LICENSE ├── README.md ├── SUMMARY.md ├── boeluem-1 ├── aritmetik-operatoerler.md ├── atama-operatoerleri.md ├── bilgisayariniz-uezerinde-go-gelistirme.md ├── degiskenler-ve-atanmasi.md ├── farkli-platformlara-build-insa-etme.md ├── go-derleyicisi-kurulumu.md ├── go-projesi-olusturma.md ├── golang-hakkinda.md ├── iliskisel-operatoerler.md ├── klasoer-build-etme.md ├── kod-gruplama-islemi.md ├── mantiksal-operatoerler.md ├── merhaba-duenya.md ├── paketler.md ├── sabitler.md ├── sikca-sorulan-sorular.md ├── tuer-doenuesuemue.md ├── veri-tipleri.md ├── vscode-varsayilan-hata-ayiklayiciyi-secme.md └── yorum-satiri.md ├── boeluem-2 ├── anonim-fonksiyonlar.md ├── bos-tanimlayicilar.md ├── defer.md ├── doengueler.md ├── fonksiyon-cesitleri.md ├── fonksiyonlar.md ├── if-else.md ├── pointers-isaretciler.md └── switch.md ├── boeluem-3 ├── anonim-struct-metodlar.md ├── arayuez-interface.md ├── dilimler-slices.md ├── diziler-arrays.md ├── generics.md ├── map.md ├── range.md ├── struct-fonksiyonlar-methodlar.md └── struct.md ├── boeluem-4 ├── anonim-goroutine-fonksiyonlar.md ├── kanallar-channels.md ├── mutex-ile-asenkron-islem-sirasi.md ├── select.md ├── untitled.md ├── waitgroup-ile-goroutinein-tamamlanmasini-beklemek.md └── zamanlayicilar-tickers.md ├── boeluem-5 ├── cok-satirli-string-olusturma.md ├── disa-aktarma-exporting.md ├── format-ve-kacis-karakterleri.md ├── golangte-kullanicidan-giris-alma.md ├── import-kuetuephane-ekleme-yoentemleri.md ├── init-fonksiyonu-oen-yuekleme.md ├── panic-and-recover.md ├── print-fonksiyonu-birkac-inceleme.md ├── sprintf.md └── testing-test-etme.md ├── boeluem-6-paketler ├── komut-satiri-arguemanlari-args.md ├── komut-satiri-bayraklari-flags.md ├── log-kayit.md ├── os-exec-komut-satirina-erisim.md ├── os-signal.md ├── paket-kuetuephane-yazmak.md ├── regexp-kuralli-ifadeler.md ├── sort-siralama.md ├── strconv-string-ceviri.md └── strings.md ├── boeluem-7-dosya-islemleri ├── bir-dizindeki-dosya-ve-klasoerleri-siralama.md ├── capraz-platform-dosya-yollari.md ├── chromedp-web-driver.md ├── dosya-varligi-kontrolue.md ├── ini-dosyasi-okuma-ve-duezenleme.md ├── ioutil-ile-dosya-okuma-ve-yazma.md ├── isletim-sistemini-goerme.md ├── json-parsing-ayristirma.md ├── json-parsing-ayristirma │ ├── README.md │ └── dinamik-json-parsing-yoentemleri.md ├── web-scrapper.md └── xml-parsing-ayristirma.md ├── cli └── cobra-cli.md ├── go-programlama-dili.epub ├── golangtrlogo.png ├── gopher.png ├── goprogramlamadiliv1.pdf ├── goprogramlamadiliv2.pdf ├── goprogramlamadiliv3.pdf ├── goprogramlamadiliv4.pdf ├── gui ├── notify-bildirim.md └── webview.md ├── kapaktanitim.png ├── kitap-hakkinda └── katkida-bulunanlar.md ├── mikro-denetleyiciler ├── gobot-ile-arduino-yanip-soenen-led-yapimi.md └── tinygo-ile-kuecuek-yerler-icin-golang.md ├── pratik-bilgiler ├── derleme-build-detayini-goerme.md ├── dinamik-degiskenler.md ├── go-gelistiricileri-icin-makefile.md ├── isletim-sistemini-goerme.md └── visual-studio-code-icin-golang-oezellestirmeleri.md ├── veritabani ├── gorm.md ├── mongodb.md ├── mysql.md └── sqlite3.md ├── web-sunucu-server-ag-istemleri ├── gin-web-kuetuephanesi │ ├── README.md │ └── gin-dosya-yuekleme.md ├── grpc.md ├── herokuda-go-uygulamasi-yayinlama.md ├── html-sablonlar-templates.md ├── net-http-ile-web-server-olusturma.md ├── rabbitmq │ ├── README.md │ ├── basitce-rabbitmq-kullanimi.md │ └── rabbitmq-kurulumu.md ├── requests.md └── statik-kuetuephanesi-ile-dosyalari-uygulamaya-goemme.md └── yapilandirma └── viper.md /.gitbook/assets/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.gitbook/assets/2020-11-09_23-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/2020-11-09_23-38.png -------------------------------------------------------------------------------- /.gitbook/assets/2020-11-23_22-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/2020-11-23_22-30.png -------------------------------------------------------------------------------- /.gitbook/assets/2020-11-23_22-38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/2020-11-23_22-38.png -------------------------------------------------------------------------------- /.gitbook/assets/3208a2431252c05f682be6a81259afa1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/3208a2431252c05f682be6a81259afa1.jpeg -------------------------------------------------------------------------------- /.gitbook/assets/88iU5v.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/88iU5v.webp -------------------------------------------------------------------------------- /.gitbook/assets/DeepinScreenshot_select-area_20191006213837.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/DeepinScreenshot_select-area_20191006213837.webp -------------------------------------------------------------------------------- /.gitbook/assets/DeepinScreenshot_select-area_20200123205023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/DeepinScreenshot_select-area_20200123205023.png -------------------------------------------------------------------------------- /.gitbook/assets/EvYnc-5VoAEOSTV.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/EvYnc-5VoAEOSTV.jpeg -------------------------------------------------------------------------------- /.gitbook/assets/Screen Shot 2022-05-06 at 22.26.18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/Screen Shot 2022-05-06 at 22.26.18.png -------------------------------------------------------------------------------- /.gitbook/assets/Screenshot_20201012_130620.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/Screenshot_20201012_130620.png -------------------------------------------------------------------------------- /.gitbook/assets/ampkullanımı.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/ampkullanımı.png -------------------------------------------------------------------------------- /.gitbook/assets/archlinux-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/archlinux-icon.png -------------------------------------------------------------------------------- /.gitbook/assets/bc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/bc.png -------------------------------------------------------------------------------- /.gitbook/assets/cobra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/cobra.png -------------------------------------------------------------------------------- /.gitbook/assets/dbbrowser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/dbbrowser.png -------------------------------------------------------------------------------- /.gitbook/assets/debian-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/debian-icon.png -------------------------------------------------------------------------------- /.gitbook/assets/defaultdebugger1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/defaultdebugger1.png -------------------------------------------------------------------------------- /.gitbook/assets/defaultdebugger2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/defaultdebugger2.png -------------------------------------------------------------------------------- /.gitbook/assets/defaultdebugger3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/defaultdebugger3.png -------------------------------------------------------------------------------- /.gitbook/assets/errorlens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/errorlens.png -------------------------------------------------------------------------------- /.gitbook/assets/gin-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/gin-json.png -------------------------------------------------------------------------------- /.gitbook/assets/gin-param.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/gin-param.png -------------------------------------------------------------------------------- /.gitbook/assets/gin-querystring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/gin-querystring.png -------------------------------------------------------------------------------- /.gitbook/assets/github-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/github-image.png -------------------------------------------------------------------------------- /.gitbook/assets/go-gin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/go-gin.png -------------------------------------------------------------------------------- /.gitbook/assets/go-mod-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/go-mod-init.png -------------------------------------------------------------------------------- /.gitbook/assets/golang-grpc-example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/golang-grpc-example.gif -------------------------------------------------------------------------------- /.gitbook/assets/golang-plugins-all.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/golang-plugins-all.webp -------------------------------------------------------------------------------- /.gitbook/assets/golangtrsitelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/golangtrsitelogo.png -------------------------------------------------------------------------------- /.gitbook/assets/gorm1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/gorm1.png -------------------------------------------------------------------------------- /.gitbook/assets/heroku-create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/heroku-create.png -------------------------------------------------------------------------------- /.gitbook/assets/heroku-login-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/heroku-login-success.png -------------------------------------------------------------------------------- /.gitbook/assets/heroku-login-warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/heroku-login-warning.png -------------------------------------------------------------------------------- /.gitbook/assets/heroku-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/heroku-login.png -------------------------------------------------------------------------------- /.gitbook/assets/heroku-push.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/heroku-push.png -------------------------------------------------------------------------------- /.gitbook/assets/heroku-site.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/heroku-site.png -------------------------------------------------------------------------------- /.gitbook/assets/htmlw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/htmlw.png -------------------------------------------------------------------------------- /.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/image (4) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/image (4).png -------------------------------------------------------------------------------- /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/image.png -------------------------------------------------------------------------------- /.gitbook/assets/instagram-sketched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/instagram-sketched.png -------------------------------------------------------------------------------- /.gitbook/assets/jskonsole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/jskonsole.png -------------------------------------------------------------------------------- /.gitbook/assets/ken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/ken.png -------------------------------------------------------------------------------- /.gitbook/assets/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/linux.png -------------------------------------------------------------------------------- /.gitbook/assets/linuxmint-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/linuxmint-icon.png -------------------------------------------------------------------------------- /.gitbook/assets/livedebug.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/livedebug.gif -------------------------------------------------------------------------------- /.gitbook/assets/macos (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/macos (1).png -------------------------------------------------------------------------------- /.gitbook/assets/manjaro-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/manjaro-icon.png -------------------------------------------------------------------------------- /.gitbook/assets/mutex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/mutex.png -------------------------------------------------------------------------------- /.gitbook/assets/no-vendor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/no-vendor.png -------------------------------------------------------------------------------- /.gitbook/assets/package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/package.png -------------------------------------------------------------------------------- /.gitbook/assets/pointeronram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/pointeronram.png -------------------------------------------------------------------------------- /.gitbook/assets/pointeryanlış.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/pointeryanlış.png -------------------------------------------------------------------------------- /.gitbook/assets/prefer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/prefer.png -------------------------------------------------------------------------------- /.gitbook/assets/prefer2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/prefer2.png -------------------------------------------------------------------------------- /.gitbook/assets/protoc-download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/protoc-download.png -------------------------------------------------------------------------------- /.gitbook/assets/rob.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/rob.jpg -------------------------------------------------------------------------------- /.gitbook/assets/robert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/robert.png -------------------------------------------------------------------------------- /.gitbook/assets/salca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/salca.png -------------------------------------------------------------------------------- /.gitbook/assets/ssss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/ssss.png -------------------------------------------------------------------------------- /.gitbook/assets/statik.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/statik.png -------------------------------------------------------------------------------- /.gitbook/assets/str.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/str.png -------------------------------------------------------------------------------- /.gitbook/assets/telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/telegram.png -------------------------------------------------------------------------------- /.gitbook/assets/thumnailgolang.jpeg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/thumnailgolang.jpeg.png -------------------------------------------------------------------------------- /.gitbook/assets/tinygo-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/tinygo-logo.png -------------------------------------------------------------------------------- /.gitbook/assets/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/twitter.png -------------------------------------------------------------------------------- /.gitbook/assets/u2XPpO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/u2XPpO.png -------------------------------------------------------------------------------- /.gitbook/assets/uEIcZ3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/uEIcZ3.webp -------------------------------------------------------------------------------- /.gitbook/assets/uber go style guide tr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitbook/assets/ubuntu-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/ubuntu-icon.png -------------------------------------------------------------------------------- /.gitbook/assets/viper-logo (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/viper-logo (1).png -------------------------------------------------------------------------------- /.gitbook/assets/viper-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/viper-logo.png -------------------------------------------------------------------------------- /.gitbook/assets/vt3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/vt3.png -------------------------------------------------------------------------------- /.gitbook/assets/windows (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/windows (1).png -------------------------------------------------------------------------------- /.gitbook/assets/workflow-rabbitmq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/workflow-rabbitmq.png -------------------------------------------------------------------------------- /.gitbook/assets/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/.gitbook/assets/youtube.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [ksckaan1] 4 | -------------------------------------------------------------------------------- /Golang Örnekler/Kullanıcı Bilgi Sistemi/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var isim, soyisim, tcno string 9 | var yas int 10 | var tekrar = int(1) 11 | for tekrar == 1 { 12 | fmt.Print("İsminiz-Soyisminiz Nedir?: ") 13 | fmt.Scanf("%s %s", &isim, &soyisim) 14 | if isim == "" || soyisim == "" { 15 | fmt.Println("\nİsim veya Soyisim Boş Girilemez.") 16 | } else { 17 | break 18 | } 19 | } 20 | for tekrar == 1 { 21 | fmt.Printf("\nMerhaba %s, Kaç Yaşındasın?: ", isim) 22 | fmt.Scanf("%d", &yas) 23 | if yas == 0 || yas < 0 { 24 | fmt.Println("\nGeçersiz Yaş Girdiniz.") 25 | } else { 26 | break 27 | } 28 | } 29 | for tekrar == 1 { 30 | fmt.Print("\nTC NO'nuz Nedir?: ") 31 | fmt.Scanf("%s", &tcno) 32 | if len(tcno) != 11 { 33 | fmt.Println("\nTC NO'nuz 11 Haneli olmalıdır.") 34 | } else { 35 | break 36 | } 37 | } 38 | 39 | fmt.Printf("\nİŞTE TÜM BİLGİLERİNİZ\nİsim-Soyisim: %s %s\nYaş: %d\nTC NO: %s", isim, soyisim, yas, tcno) 40 | fmt.Scanf("%s") 41 | } 42 | -------------------------------------------------------------------------------- /Golang Örnekler/Pisagor Hesaplama/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | var ken1, ken2, hipo float64 10 | 11 | fmt.Println("Dik üçgende Hipotenüs bulma programına hoşgeldiniz!") 12 | fmt.Print("1. kenarı girin: ") 13 | fmt.Scan(&ken1) 14 | fmt.Print("\n2. kenarı girin: ") 15 | fmt.Scan(&ken2) 16 | hipo = math.Sqrt(math.Pow(ken1, 2) + math.Pow(ken2, 2)) 17 | fmt.Printf("\nHipotenüs: %f\n Çıkmak için [ENTER] tuşuna basın...", hipo) 18 | fmt.Scanf("%s") 19 | } 20 | -------------------------------------------------------------------------------- /Golang Örnekler/Sayı Tahmin/sayitahmin.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" //Genel 5 | "math/rand" //rastgele sayı için 6 | "os" //Sistem 7 | "os/exec" //terminalde kod yürütme için 8 | "runtime" //Çalışma ortamı kodları için 9 | "strconv" //String'e çevirmek için 10 | "time" //Zaman fonksiyonları için 11 | ) 12 | 13 | func main() { 14 | 15 | s1 := rand.NewSource(time.Now().UnixNano()) 16 | r1 := rand.New(s1) 17 | sayi := strconv.Itoa(r1.Intn(10)) //rastgele sayı oluşturduk 18 | döngü := true 19 | temizle() 20 | fmt.Println("Sayı tahmin oyunu") 21 | fmt.Print("Sayı yazın: ") 22 | var tahmin string 23 | for döngü == true { //döngü true iken çalışacak 24 | 25 | fmt.Scanf("%s", &tahmin) 26 | if tahmin == sayi { 27 | döngü = false 28 | temizle() 29 | fmt.Printf("Tebrikler Doğru sayı: %s", sayi) 30 | } else if tahmin > sayi { 31 | temizle() 32 | fmt.Print("Bilemediniz,Tahmini küçültün\nSayı Yazın: ") 33 | } else { 34 | temizle() 35 | fmt.Print("Bilemediniz,Tahmini büyütün\nSayı Yazın: ") 36 | } 37 | } 38 | } 39 | func temizle() { //Terminal Temizleme 40 | if runtime.GOOS == "linux" { 41 | cmd := exec.Command("clear") 42 | cmd.Stdout = os.Stdout 43 | cmd.Run() 44 | } else { 45 | cmd := exec.Command("cls") 46 | cmd.Stdout = os.Stdout 47 | cmd.Run() 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Golang Örnekler/Sunucu Oluşturucu/sunucuolusturucu.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | port := "8000" 10 | klasor := "" 11 | fmt.Println(" ____ _ _ _ _ _ _ ____ _ _ ___ _ _ _ ____ _____ _ _ ____\n/ ___|| | | | \\ | | | | |/ ___| | | | / _ \\| | | | | / ___|_ _| | | | _ \\\n\\___ \\| | | | \\| | | | | | | | | | | | | | | | | | \\___ \\ | | | | | | |_) |\n ___) | |_| | |\\ | |_| | |___| |_| | | |_| | |__| |_| |___) || | | |_| | _ < \n|____/ \\___/|_| \\_|\\___/ \\____|\\___/ \\___/|_____\\___/|____/ |_| \\___/|_| \\_\\") 12 | fmt.Println("####################################################################") 13 | son := "####################################################################" 14 | fmt.Printf("Oluşturulacak portu giriniz (8000 için boş bırakın): ") 15 | fmt.Scanf("%s", &port) 16 | if port == "" { 17 | port = "8000" 18 | } else if len(port) < 4 { 19 | port = "8000" 20 | fmt.Println("Portu 4 karakterden az girdiğiniz için 8000 olarak ayarlandı") 21 | } else if len(port) > 4 { 22 | port = "8000" 23 | fmt.Println("Portu 4 karakterden fazla girdiğiniz için 800 olarak ayarlandı") 24 | } 25 | fmt.Printf("Klasörün ismini giriniz (/ olmadan): ") 26 | fmt.Scanf("%s", &klasor) 27 | http.Handle("/", http.FileServer(http.Dir(klasor))) 28 | fmt.Printf("http://localhost:%s oluşturuldu\n%s", port, son) 29 | http.ListenAndServe(":"+port, nil) 30 | } 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GİRİŞ 2 | 3 | **Giriş** 4 | 5 | Bu eğitim kaynağında Golang programlama dili hakkında bilgilerdirici ön yazı, kullanım şekline ve örneklerine bakacağız. Bu kitapla pratik yapabilirsiniz. Kitap ileri seviye Go programlama içermeyecektir. 6 | 7 | **Bu Kitap Kimlere Hitap Ediyor?** 8 | 9 | Bu kitap; 10 | 11 | * Go programlama dilini öğrenmek isteyen, 12 | * Go’da giriş seviyesinde bilgi sahibi olan, 13 | * Go’da orta seviyede bilgi sahibi olan, 14 | * veya daha önce başka dillere aşina olan, 15 | 16 | kişilere hitap ediyor 17 | 18 | **Amaç** 19 | 20 | Kitabın Amacı; 21 | 22 | * Golang için Türkçe kaynak oluşturmak 23 | * Golang için ücretsiz eğitim kaynağı oluşturmak 24 | * Golang dilinin temel yapısını öğretmek 25 | 26 | **Kitabın İçeriği Hakkında** 27 | 28 | Kitabın içeriğinde Go programlama dilinden “Go”, “Golang” ve “Go Programlama Dili” olarak bahsediyor olunacaktır. Hepsi aynı anlama geliyor. Genellikle kodların kullanım şekli ve yapısından bahsedilecektir. Tabi ki işleyişi anlayabilmemiz için örnekler ile pekiştirilecektir. 29 | 30 | Bu kitap sayesinde ülkemizde şuanda diğer dillere göre daha az bilinen ve hakkında fikir sahibi olan kişilerin sayısı az olan bu programlama dili hakkında kaynak oluşturulacaktır. 31 | -------------------------------------------------------------------------------- /boeluem-1/aritmetik-operatoerler.md: -------------------------------------------------------------------------------- 1 | # Aritmetik Operatörler 2 | 3 | Aritmetik operatörler programlamada matematiksel işlemler yapabilmemize olanak sağlar. 4 | 5 | | Operatör | Açıklama | Örnek | 6 | | -------- | --------------------------- | ----- | 7 | | + | Toplar | 2+5 | 8 | | - | Çıkarır | 10-3 | 9 | | \* | Çarpar | 3\*4 | 10 | | / | Böler | 10/2 | 11 | | % | Bölümden kalanı verir (Mod) | 10%3 | 12 | | ++ | 1 arttırır | 1++ | 13 | | -- | 1 eksiltir | 1-- | 14 | -------------------------------------------------------------------------------- /boeluem-1/atama-operatoerleri.md: -------------------------------------------------------------------------------- 1 | # Atama Operatörleri 2 | 3 | Atama operatörleri değişkenlere ve sabitlere değer atamak için kullanılır. Aşağıdaki tabloda c’nin değeri 10’dur. (c=10) 4 | 5 | | Operatör | Açıklama | Örnek | 6 | | -------- | ------------------------------ | ----- | 7 | | = | Atama Operatörüdür | c=2 | 8 | | += | Kendiyle toplar | c+=2 | 9 | | -= | Kendinden çıkarır | c-=2 | 10 | | \*= | Kendiyle çarpar | c\*=2 | 11 | | /= | Kendine böler | c/=2 | 12 | | %= | Kendine bölümünden kalanı atar | c%=3 | 13 | -------------------------------------------------------------------------------- /boeluem-1/bilgisayariniz-uezerinde-go-gelistirme.md: -------------------------------------------------------------------------------- 1 | # VSCode Go Eklentisi Yükleme 2 | 3 | Go'yu indirdiğimize göre bize Go kodlarımızı yazacağımız bir Tümleşik Geliştirme Ortamı (IDE) lazım. IDE’ler kodlarımızı yazarken kodların doğruluğunu kontrol eder ve kod yazarken önerilerde bulunur. Bu da kod yazarken işimizi kolaylaştırır. 4 | 5 | Çoğu programlama dili ile geliştirme yaparken kullanılan ve Go yazanların da popüler olarak kullandığı **Visual Studio Code** programınu kullanabilirsiniz. 6 | 7 | Buradan İndirebilirsiniz 8 | 9 | [https://code.visualstudio.com/Download](https://code.visualstudio.com/Download) 10 | 11 | GNU/Linux OS kullananlara yine kullandıkları dağıtımın uygulama deposundan indirmeleri tavsiye edilir. 12 | 13 | Visual Studio Code’dan ileriki zamanlarda **vscode** olarak bahsedilecek. 14 | 15 | Go eklentisinin düzgün bir şekilde kurulabilmesi için bilgisayarımızda **git** komut-satırı uygulaması bulunması gerekir. Çünkü eklentinin yüklenmesinden sonra Go eklentisi VSCode için 15 civarı aracı otomatik indirecek. Git’in yüklü olup olmadığını öğrenmek için komut satırına aşağıdakileri yazın: 16 | 17 | Eğer versiyon numarasını gördüyseniz yüklü demektir. Eğer yüklü değilse veya git’i güncellemek istiyorsanız ki, mutlaka öneririm, aşağıda nasıl yükleneceğini görebilirsiniz. 18 | 19 | `git --version` 20 | 21 | ### Windows MacOS 22 | 23 | Windows için: [Buradan İndirebilirsiniz](https://git-scm.com/download/win) 24 | 25 | MacOS: [Buradan İndirebilirsiniz.](https://git-scm.com/download/mac) 26 | 27 | ### **GNU/Linux İşletim Sistemleri** 28 | 29 | #### **Debian/Ubuntu** 30 | 31 | `sudo apt-get install git` 32 | 33 | #### **Fedora** 34 | 35 | `dnf install git` 36 | 37 | #### **Arch Linux** 38 | 39 | `sudo pacman -S git` 40 | 41 | #### **Gentoo** 42 | 43 | `emerge --ask --verbose dev-vcs/git` 44 | 45 | #### **openSUSE** 46 | 47 | `zypper install git` 48 | 49 | #### **Mageia** 50 | 51 | `urpmi git` 52 | 53 | Git kurulumunu da yaptığımıza göre VSCode için Go eklentisini kurabiliriz. 54 | 55 | ![VS Code Go Eklentisi](../.gitbook/assets/DeepinScreenshot\_select-area\_20191006213837.webp) 56 | 57 | Vscode’un sol tarafından **Extension** (Eklentiler) sekmesine geçiyoruz. Arama kutusuna **go** yazıyoruz. Resimde de seçili olan Go eklentisini yeşil **Install (Yükle)** butonuna basarak yüklüyoruz. Yeniden başlatma isterse başlatmayı unutmayın. 58 | 59 | Daha sonra **main.go** adında bir dosya oluşturup VSCode ile açalım. main.go dosyasının içerisine rastgele birşeyler yazdığımızda VSCode sağ alt tarafta bize uyarı verecektir. 60 | 61 | ![VS Code Go Uyarısı](../.gitbook/assets/golang-plugins-all.webp) 62 | 63 | **Install All** diyerek Go geliştirmemize yazrdımcı olacak araçların kurulumunu başlatalım. 64 | 65 | Kurulum bize 15 civarı araç kuracak. Başarı ile kurulan araçların yanında **SUCCEED** ibaresi yer alır. 66 | 67 | Tüm araçlarımız başarıyla kurulunca artık VSCode üzerinden Go geliştirmeye hazır olacaksınız. 68 | 69 | ## 70 | -------------------------------------------------------------------------------- /boeluem-1/degiskenler-ve-atanmasi.md: -------------------------------------------------------------------------------- 1 | # Değişkenler ve Atanması 2 | 3 | **Değişkenler** içerisinde değer barındırarak RAM’e kaydettiğimiz bilgilerdir. Değişkenler programımızın işleyişinde önemli bir role sahiptir. Değişkenleri şu şekillerde atayabiliriz. Değişkenler **var** ifadesi ile atanır. Tabi ki zorunlu değildir. 4 | 5 | ```go 6 | var isim string = “Ali” 7 | var yas int = 20 8 | var ogrenci bool = true 9 | ``` 10 | 11 | Yukarıdaki yazdıklarımızı inceleyecek olursak; 12 | 13 | **var** ile değişken atadığımızı belirtiyoruz. **isim** diye bir değişken adı atadık ve içine **“Ali**” değerinde **string** tipinde bir değer yerleştirdik. String tipi değerler çift tırnak içine yazılır. 14 | 15 | Aynı şekilde **yas** adında değişken oluşturduk. **yas** değişkeni içerisine **int** tipinde **20** değerini yerleştirdik Son olarak **ogrenci** adında bir değişken oluşturduk ve **true** değerinde **boolean** tipinde bir atama yaptık. 16 | 17 | Golang’ta değişken adı oluştururken Türkçe karakterler kullanabiliriz. Örnek olarak **ogrenci** yerine öğrenci yazabilirdik. Ama başka bir programlama diline geçtiğinizde Türkçe harf desteklememesi halinde alışkanlıklarınızı değiştirmeniz gerekecek. O yüzden Türkçe karakter kullanmamanızı tavsiye ederim. Tabi ki zorunlu değil. 18 | 19 | Programlama dillerinde, matematiğin aksine **= (eşittir)** işareti eşitlik için değil, atamalar için kullanılır. 20 | 21 | Değişkenlerin atanması için farklı yöntemler de var. Diğer yöntemlere değinmek gerekirse; 22 | 23 | Değişken atamasında illaki değişkenin veri tipini belirtmemiz gerekmez. Yazdığımız değere göre Golang otomatik olarak veri tipini algılar. 24 | 25 | ```go 26 | var isim = “Ali” 27 | var yas = 20 28 | var ogrenci = true 29 | ``` 30 | 31 | **isim** değişkeninin değerini çift tırnak arasına yazdığımız için **string** veri tipinde olduğunu algılayacaktır. 32 | 33 | **yas** değişkeninin değerini sayı olarak girdiğimiz için **int** tipinde olduğunu algılar. Eğer 20 değil de 2.12312 gibi küsüratlı bir değer girseydik veri tipini **float** olarak algılardı. 34 | 35 | **ogrenci** değişkeninin değerini mantıksal olarak girdiğimiz için **boolean** veri tipinde olduğunu algılayacaktır. 36 | 37 | En basit şekilde değişken ataması yapmak istersek; 38 | 39 | ```go 40 | isim:=”Ali” 41 | yas:=20 42 | ogrenci:=true 43 | ``` 44 | 45 | Başına **var** eklemeden de değişken atamak mümkündür. Bu şekilde yapmak için **:=** işaretlerini kullanırız. Aynı şekilde bu yöntemde de verinin tipi otomatik algılanır. 46 | 47 | Eğer değişken tanımlar iken değer kısmını boş bırakırsak yani; **var yas int** şeklinde yazarsak, önceki konuda da bahsettiğimiz gibi varsayılan olarak **0** değerini alır. 48 | -------------------------------------------------------------------------------- /boeluem-1/farkli-platformlara-build-insa-etme.md: -------------------------------------------------------------------------------- 1 | # Farklı Platformlara Build (İnşa) Etme 2 | 3 | Golang projemizi build (inşa) ederken, yani çalıştırılabilir bir dosya üretirken **go build dosya.go** şeklinde build ederiz. Bu işlem varsayılan olarak kullanmakta olduğumuz işletim sistemi için build işlemi yapar. Yani Windows kullanıyorsak Windows’ta çalışmak üzere Linux İS kullanıyorsak Linux İS’te çalışmak üzere dosya oluşturur. Aynı şekilde sistemimizin mimarisi 32bit ise 32bit için, 64bit ise 64bit için çalıştırılabilir dosya üretir. Örnek olarak sistemimiz Windows 64bit ise oluşturduğumuz çalıştırılabilir dosya (exe dosyası) sadece Windows 64bitlerde çalışır. 4 | 5 | Eğer farklı işletim sistemi için bir çalıştırılabilir dosya üretmek istiyorsak aşağıdaki komutu kullanmamız gerekir. 6 | 7 | `env GOOS=hedef-sistem GOARCH=hedef-mimari go build hedef-dosya` 8 | 9 | Örnek olarak, **main.go** dosyamızı **Windows 32bit** sistemler için build etmek istersek aşağıdaki komutları girmemiz gerekir. 10 | 11 | `env GOOS=windows GOARCH=386 go build main.go` 12 | 13 | Bu işlem ile main.exe adında bir dosya elde ederiz. Bu dosya Windows 32bit sistemlerde çalışabilir. Biliyorsunuz ki 32bit uygulamalar 64bit sistemlerde çalışır ;fakat 64bit uygulamalar 32bit sistemlerde çalışmaz. Onun için bir uygulama build ediyorken bunu aklınızdan çıkarmayın. Golang’ın dosya build edebildiği işletim sistemi ve mimari sayısı oldukça fazladır. 14 | 15 | Golang’ın build edebildiği tüm işletim sistemi ve mimarilerine bakmak gerekir ise; 16 | 17 | | GOOS | GOARCH | 18 | | --------- | -------- | 19 | | android | arm | 20 | | darwin | 386 | 21 | | darwin | amd64 | 22 | | darwin | arm | 23 | | darwin | arm64 | 24 | | dragonfly | amd64 | 25 | | freebsd | 386 | 26 | | freebsd | amd64 | 27 | | freebsd | arm | 28 | | linux | 386 | 29 | | linux | amd64 | 30 | | linux | arm | 31 | | linux | arm64 | 32 | | linux | ppc64 | 33 | | linux | ppc64le | 34 | | linux | mips | 35 | | linux | mipsle | 36 | | linux | mips64 | 37 | | linux | mips64le | 38 | | netbsd | 386 | 39 | | netbsd | arm64 | 40 | | netbsd | arm | 41 | | openbsd | 386 | 42 | | openbsd | arm64 | 43 | | openbsd | arm | 44 | | plan9 | 386 | 45 | | plan9 | amd64 | 46 | | solaris | amd64 | 47 | | windows | 386 | 48 | | windows | amd64 | 49 | 50 | \* Tablo harf sıralamasına göre yapılmıştır. 51 | 52 | Birkaç örnek daha yapmak gerekirse; 53 | 54 | **Windows 64bit Build** 55 | 56 | `env GOOS=windows GOARCH=amd64 go build main.go` 57 | 58 | **Linux 32bit Build** 59 | 60 | `env GOOS=linux GOARCH=386 go build main.go` 61 | 62 | **MacOS 64bit Build** 63 | 64 | `env GOOS=darwin GOARCH=amd64 go build main.go` 65 | -------------------------------------------------------------------------------- /boeluem-1/go-derleyicisi-kurulumu.md: -------------------------------------------------------------------------------- 1 | # Go Derleyicisi Kurulumu 2 | 3 | Öncelikle bilgisayarımız üzerinde nasıl Go ile yazılım geliştireceğimize bakalım. Öncelikle Golang’ın resmi sitesinden Go derleyiciyi indiriyoruz. 4 | 5 | Buradan İndirebilirsiniz 6 | 7 | [https://golang.org/dl/](https://golang.org/dl/) 8 | 9 | Go'nun basit bir kurulumu var o yüzden kurulumu atlıyoruz. 10 | 11 | GNU/Linux OS kullananlara tavsiye, 12 | 13 | Kullandığınız dağıtımın uygulama deposundan Golang’ı indirin. Sizin için daha kolay olur. Eğer son Go versiyonunu yüklemek istiyorsanız ve uygulama deponuzda son versiyon yoksa [https://golang.org/dl/](https://golang.org/dl/) adresinden Linux versiyonunu indirebilirsiniz. 14 | 15 | Uygulama depolarından indirmek için: 16 | 17 | | GNU/Linux Dağıtımı | Komut | 18 | | ------------------------------------------------------------------------------------------------------------------------ | ----------------------- | 19 | | ![](../.gitbook/assets/debian-icon.png)![](../.gitbook/assets/ubuntu-icon.png)![](../.gitbook/assets/linuxmint-icon.png) | sudo apt install golang | 20 | | ![](../.gitbook/assets/archlinux-icon.png)![](../.gitbook/assets/manjaro-icon.png) | sudo pacman -S go | 21 | -------------------------------------------------------------------------------- /boeluem-1/go-projesi-olusturma.md: -------------------------------------------------------------------------------- 1 | # Go Projesi Oluşturma 2 | 3 | Go kurulumu ve paket yükleme işlemleri sonrasında oluşan klasör yapısını kullanarak projeleri burada barındırabiliriz. Normalde herhangi bir klasörde Go geliştirmeniz mümkündür fakat Go geliştiricilerin doğru bulduğu klasör mimarisinde geliştirmek size daha sağlıklı bir süreç sağlayabilir. 4 | 5 | Varsayılan kurulumda `c:/users/{user-name}/go` klasöründe **bin**, **pkg**, **src** adında üç klasör oluşturulur. 6 | 7 | **bin** klasörü paket yöneticisi ile install komutu kullanılarak deploy edilen executable dosyaları barındırır. 8 | 9 | **pkg** klasörü üçüncü sınıf paketler indirildiğinde derlenmiş şekilde bu klasör altında barındırır. Aynı zamanda kaynak kodları **src** klasörüne koyar. pkg klasörü derlenme süresini hızlandırmak için halihazırda derlenmiş bir kod içerir. Kendi projelerinizde import ettiğiniz paketlerin geldiği yer burasıdır. 10 | 11 | **src** klasörü geliştirme yapacağınız projelerinizin barındırılacağı klasördür. Burada projelerinizi belirli bir düzende barındırmanız sizin için sağlıklı olacaktır. Aşağıdaki gösterilen yapıda projelerinizi geliştirebilirsiniz. Bu yapı sayesinde **Git** üzerinde bulunan projelerinizdeki karışıklığı önleyebilirsiniz. 12 | 13 | ### Varsayılan GOPATH Klasörünü Değiştirme 14 | 15 | **Yeni Yöntem** 16 | 17 | **Go modules** sayesinde Go 1.11'den beri artık GOPATH kullanmak zorunda değilsiniz. Aşağıdaki adımı herhangi bir klasörde kullanarak modülünüzü tanımlayabilirsiniz. 18 | 19 | ```bash 20 | go mod init github.com/{your-user}/{your-repo} 21 | ``` 22 | 23 | * Bu komutla o dizinde bir modül kökü oluşturulur. 24 | * İstediğiniz kadar modül oluşturabilirsiniz. 25 | 26 | **Eski Yöntem** 27 | 28 | **GOPATH** ile çalışmakta ısrar ediyorsanız aşağıdaki uyarılara dikkat etmelisiniz. 29 | 30 | * Go 1.8'den beri, GOPATH veya GOROOT'unuzu ayarlamanız gerekmez. 31 | * GOPATH varsayılan olarak **user/home** dizininizin altındadır. 32 | 33 | {% hint style="info" %} 34 | GOPATH ayarlanmadıysa, Unix sistemlerinde $HOME/go ve Windows'ta `%USERPROFILE%\go` olduğu varsayılır. Çalışma alanınız olarak özel bir konum kullanmak istiyorsanız, GOPATH ortam değişkenini ayarlayabilirsiniz. 35 | {% endhint %} 36 | 37 | Özel çalışma alanı ayarlamak için aşağıdaki komutları kullanabilirsiniz. 38 | 39 | ```bash 40 | export GOROOT=/usr/lib/go 41 | export GOPATH=$HOME/go 42 | export PATH=$PATH:$GOROOT/bin:$GOPATH/bin 43 | ``` 44 | -------------------------------------------------------------------------------- /boeluem-1/golang-hakkinda.md: -------------------------------------------------------------------------------- 1 | # Golang Hakkında 2 | 3 | Golang (diğer adıyla Go), **Google**’ın **2007** yılından beri geliştirdiği açık kaynaklı programlama dilidir. Daha çok alt-sistem programlama için tasarlanmış olup, derlenebilir ve **statik** tipli bir dildir. İlk versiyonu **Kasım 2009**‘da çıkmıştır. Derleyicisi olan **“gc” (Go Compiler)** açık kaynak olarak birçok işletim sistemi için geliştirilmiştir. 4 | 5 | Golang, Google mühendislerinden olan **Robert Griesemer, Rob Pike ve Ken Thompson** tarafından ilk olarak deney amaçlı ortaya çıkmıştır. Diğer dillerdeki eleştirilen sorunlara çözüm getirmek ve iyi yönlerini korumak için çıkarılmıştır. 6 | 7 | Bu adamların daha önceden bulunmuş olduğu projelere bakacak olursak Google’ın gerçekten bu kişileri cımbızla seçtiğini anlayabiliriz. İşte Golang’ın yaratıcılarının bulunduğu projeler: 8 | 9 | | ![Ken Thompson](../.gitbook/assets/ken.png) | ![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LzCwvXTkWXBKIvbtzHZ%2F-LzDHbwlJmPgsn4Tr4UZ%2F-LzDIhOVf5\_XFkT90LKM%2Frob.jpg?alt=media\&token=c11be5e1-d017-4f10-b361-953ee37b1ca2) | ![](../.gitbook/assets/robert.png) | 10 | | :-----------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------: | 11 | | Ken Thompson | Rob Pike | Robert Griesemer | 12 | 13 | **Robert Griesemer:** Hotspot ve JVM (Java Sanal Makinesi) 14 | 15 | **Rob Pike:** UNIX ve UTF-8 16 | 17 | **Ken Thompson:** B, C, UNIX ve UTF-8 18 | 19 | **Dilin Özellikleri** 20 | 21 | * Statik yazılmıştır, fakat dinamik rahatlığındadır. 22 | * Büyük sistemlere ölçeklenebilir. 23 | * Üretken ve okunabilir olması, çok fazla zorunlu anahtar kelime ve tekrarlamaların kullanılmaması 24 | * Tümleşik Geliştirme Ortamına (IDE) ihtiyaç duyulmaması fakat desteklemesi 25 | * Ağ ve çoklu işlemleri desteklemesi 26 | * Değişken tanımında tür belirtimi isteğe bağlıdır. 27 | * Hızlı derlenme süresi 28 | * Uzak paket yöneticisi (go get) 29 | 30 | **Örnek Merhaba Dünya Uygulaması** 31 | 32 | ```go 33 | package main 34 | 35 | import "fmt" 36 | 37 | func main(){ 38 | fmt.Println("Merhaba Dünya!") 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /boeluem-1/iliskisel-operatoerler.md: -------------------------------------------------------------------------------- 1 | # İlişkisel Operatörler 2 | 3 | İlişkisel operatörler programlamada iki veriyi birbiriyle karşılaştırabilmemize olanak sağlar. Karşılaştırma doğrulanıyorsa **true** değer, doğrulanmıyorsa **false** değer alır. 4 | 5 | | Operatör | Açıklama | Örnek | 6 | | -------- | -------------------------------------------------------- | ----- | 7 | | == | İki verinin eşitliği | 2==2 | 8 | | != | İki verinin eşitsizliği | 2!=3 | 9 | | > |
  1. verinin 2. veriden büyüklüğü
| 5>3 | 10 | | < |
  1. verinin 2. veriden küçüklüğü
| 4<6 | 11 | | >= |
  1. verinin 2. veriden büyük veya eşitliği
| 4>=6 | 12 | | <= |
  1. verinin 2. veriden küçük veya eşitliği
| 3<=8 | 13 | -------------------------------------------------------------------------------- /boeluem-1/klasoer-build-etme.md: -------------------------------------------------------------------------------- 1 | # Klasör Build Etme 2 | 3 | Oluşturduğumuz **.go** dosyaları birden fazla parçadan oluşuyorsa aşağıdaki komut ile klasör içerisindeyken build işlemini yapabiliriz. 4 | 5 | `go build . //sonda nokta işareti var` 6 | 7 | Eğer klasörün dışından build işlemi yapacaksak nokta yerine klasörün yolunu girmemiz gerekir. Aşağıda gösterilmiştir. 8 | 9 | Build işleminde sadece **.go** dosyaları derlenir. Tüm dosyalar işlenip tek başına çalıştırılabilir dosyaya dönüştürülür. Yani yanındaki Html, Css, Js vs. türünde dosyalar paket içine alınmaz. Tümüyle dosyları paketlemek için ek kütüphaneler kullanabilirsiniz. Önerim **Statik** isimli kütüphanedir. İlerideki bölümlerde zaten bu kütüphaneyi kullanıyor olacağız. 10 | 11 | `go build /klasör/yolunu/buraya/girin` 12 | -------------------------------------------------------------------------------- /boeluem-1/kod-gruplama-islemi.md: -------------------------------------------------------------------------------- 1 | # Kod Gruplama İşlemi 2 | 3 | Kod gruplama işlemi çok basit bir işlemdir. Bu işlem sayesinde aynı objeler bloklara göre farklı çalışabilir. Kodları gruplama için süslü parantez kullanırız. Örneğimizi görelim. 4 | 5 | ```go 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | değişken := "bir" 12 | { 13 | değişken := "iki" 14 | fmt.Println(değişken) 15 | } 16 | fmt.Println(değişken) 17 | } 18 | ``` 19 | 20 | Çıktımızı gördükten sonra kodları açıklayayım. 21 | 22 | > iki 23 | > 24 | > bir 25 | 26 | Yukarıda **değişken** isminde değişken oluşturduk. Hemen aşağısına süslü parantez oluşturduk. İçine yine değişken adında bir değişken tanımladık. Bu iki değişken aynı kod bloğunda bulunmadığı için birbirleri ile alakası olmayacaktır. Aslında ikisi de aynı değişkendir. Sadece içindeki bloğa göre farklı bir değeri vardır. Bunu anlamanın en basit yolu pointer ile bellek adresine bakmaktır. Şimdi de örneğimizin o versiyonunu görelim. 27 | 28 | ```go 29 | package main 30 | 31 | import "fmt" 32 | 33 | func main() { 34 | değişken := "bir" 35 | { 36 | değişken := "iki" 37 | fmt.Println(değişken) 38 | fmt.Println(&değişken) 39 | } 40 | fmt.Println(değişken) 41 | fmt.Println(&değişken) 42 | } 43 | ``` 44 | 45 | **& (and)** işareti ile değişkenin bellekteki adresini öğrenebiliriz. 46 | 47 | Çıktımız şöyle olacaktır; 48 | 49 | > iki 50 | > 51 | > 0xc00008c1d0 52 | > 53 | > bir 54 | > 55 | > 0xc00008c1c0 56 | 57 | Gördüğünüz gibi bellek adresi 2 sonuçta da farklı gözüküyor. Bu ikisinin de ayrı değişkenler olduğuna işaret ediyor. 58 | -------------------------------------------------------------------------------- /boeluem-1/mantiksal-operatoerler.md: -------------------------------------------------------------------------------- 1 | # Mantıksal Operatörler 2 | 3 | Mantıksal operatörler birden fazla mantıksal veriyi kontrol eder ve kullandığımız operatöre göre mantıksal değer döndürür. 4 | 5 | | Operatör | Açıklama | Örnek | 6 | | -------- | ------------------------------------------------------------------------ | --------------------- | 7 | | && | VE operatörüdür. 2 koşulda doğruysa true değer verir | 2==2 && 2==3 (false) | 8 | | \|\| | VEYA operatörüdür. 2 koşuldan ikisi veya biri doğru ise true değer verir | 2==2 \|\| 2==3 (true) | 9 | | ! | DEĞİL operatörüdür. Koşul sonucunun tersini verir | !(2==2) (false) | 10 | -------------------------------------------------------------------------------- /boeluem-1/merhaba-duenya.md: -------------------------------------------------------------------------------- 1 | # Merhaba Dünya 2 | 3 | Programlama dünyasında gelenektir, bir programlama dili öğrenilirken ilk önce ekrana **“Merhaba Dünya”** çıktısı veren bir program yazılır. Biz de geleneği bozmadan Golang üzerinde Merhaba Dünya uygulaması yazalım. 4 | 5 | İlk önce kodları görelim. Daha sonra açıklamasını görelim. 6 | 7 | {% code title="main.go dosyası" %} 8 | ```go 9 | package main 10 | 11 | import “fmt” 12 | 13 | func main(){ 14 | fmt.Println(“Merhaba Dünya!”) 15 | } 16 | ``` 17 | {% endcode %} 18 | 19 | Şimdi yukarıdaki kodlarda neler yaptığımıza gelelim. 20 | 21 | **Package**, kod sayfalarımız arasında iletişimde bulunabilmemizi sağlar. Bu sayede içerisinde **package** değeri aynı olan kod sayfaları birbirleriyle iletişim halinde olma yeteneği kazanır. Yukarıdaki örnekte package uygulama olan sayfalar birbiriyle iletişim kurabilir. 22 | 23 | **import “fmt”** ile Golang dilinde kullanılan ana işlemler için olan kütüphanemizi içeri aktardık. 24 | 25 | **func main()** ise programımızın çalışacağı ana bölümün fonksiyonudur. Yanındaki süslü parantezler { } içine yazdığımız kodlar ile programımızda çeşitli işlemler yapabileceğiz. Derlenmiş bir uygulama ilk olarak **main** fonksiyonuna bakar ve buradaki kodları çalıştırır. 26 | 27 | Yukarıda **import** ettiğimiz **fmt** kütüphanesi içinden **Println** fonksiyonu ile ekranımıza **“Merhaba Dünya”** yazısını bastırdık. Gelelim programımızın derlenmesine. Daha önceden programlama dilleriyle geçmişi olmayan arkadaşlarımız için derlenme şöyle anlatılabilir. Yazdığımız Golang dili insanların kolaylıkla programlama yapabilmesi için oluşturulmuş bir dildir. 28 | 29 | Ama makine (bilgisayar) bu yazdıklarımızı anlamaz. O yüzden her derlenen dilde olduğu gibi Golang’ın da yazdıklarımızı makinenin anlayacağı makine diline çeviren derleyicisi vardır. 30 | 31 | Makinemiz üzerinde çalıştırılabilir bir dosya üretmek için kodlarımızın derlenmesi gereklidir. Vscode üzerinden kodlarımızın derlenip çalışması için **F5** tuşuna basıyoruz. Böylece programımızı test edebiliriz. Eğer vscode üzerinden derliyorsanız yazdığımız kodların hemen altında **DEBUG CONSOLE** bölümünde kodumuzun sonuç çıktısını görebiliriz. 32 | 33 | Çıktımızı inceleyecek olursak, **API server listening at :127.0.0.1:44830** ibaresinde gerçekleşen olay, Golang kodlarımızı çalıştırdığımızda oluşturulan **44830** portlu **127.0.0.1** yerel sunucusu (localhost) üzerinden kodlarımızın sürüş testini gerçekleştirdik. Hemen aşağısına da çıktımızı verdi. 34 | 35 | Eğer vscode üzerinden değil de, konsol üzerinden yapmak isterseniz, oluşturmuş olduğumuz main.go dosyasının bulunduğu dizin (klasör) içerisinde konsol uygulamamızı açıyoruz. Windows’ta cmd veya Powershell’dir. Unix sistemlerde terminal diye geçer. İki tarafa da yazacağımız komutlar aynıdır. O yüzden hangisinden yazdığınız farketmez. 36 | 37 | Kodlarımızı sadece denemek istiyorsak yazacağımız komut:: 38 | 39 | `go run main.go //main.go yerine .go dosyamızın ismi gelecek` 40 | 41 | Eğer çalıştırılabilir bir dosya oluşturmak istiyorsak (Windows’ta .exe) 42 | 43 | `go build main.go //main.go yerine .go dosyamızın ismi gelecek` 44 | 45 | Böylece bu işlemleri yaptığımız dizin içerisine çalıştırılabilir bir dosya oluşturmuş olduk. 46 | 47 | Windows üzerinden konsola **main** yazarak uygulamayı açabilir veya klasörde **main.exe** dosyasına çift tıklayarak uygulamayı çalıştırabilirsiniz. 48 | 49 | Linux üzerinden ise terminale derlenmiş main çıktınızın bulunduğu dizinde **./main** yazarak çalıştırabilirsiniz. 50 | 51 | Böylece ilk uygulamamızı yazmış olduk. Tabi şu ana kadar görmemiş olduğumuz kodlar gördük. Onların açıklamaları da ileriki bölümlerde olacak. Şimdilik gelenek diye ilk bölümde **Merhaba Dünya** uygulaması yazdık. 52 | -------------------------------------------------------------------------------- /boeluem-1/paketler.md: -------------------------------------------------------------------------------- 1 | # Paketler 2 | 3 | Her Golang programı paketlerden oluşur ve kendisi de bir pakettir. 4 | 5 | ```go 6 | package uygulama 7 | 8 | import "fmt" 9 | 10 | func main() { 11 |  fmt.Println("Merhaba Dünya") // Çıktımız 12 | } 13 | ``` 14 | 15 | **package** terimi ile programımızın paket adını belirleriz. Hemen aşağısında da **import “fmt”** ile **fmt** paketini çektiğimizi görebilirsiniz. Yani çektiğimiz fmt paketi de bir programdır. Bilin bakalım fmt paketinin ilk satırında ne yazıyor? Tabiki de **package fmt**. Yani package ile programımızın ismini tanımlıyoruz. Bu ismi kullanarak diğer paketler ile iletişimde bulunabiliriz. 16 | 17 | **import** terimi ise yazıldığı pakete başka bir paketten bir yetenek aktarmaya yarar. Yetenekten kastım, import edilen paketin içinde fonksiyonlar mı var? Struct’lar mı var? vs. onları içeri aktarır. 18 | 19 | ```go 20 | import ( 21 |  “fmt” 22 |  ”math” 23 | ) 24 | ``` 25 | 26 | Yukarıda birden fazla paket import etmeyi görüyoruz. **math** paketi bize ileri matematiksel işlemler yapabilmemiz için gerekli fonksiyonları sağlar. 27 | -------------------------------------------------------------------------------- /boeluem-1/sabitler.md: -------------------------------------------------------------------------------- 1 | # Sabitler 2 | 3 | Sabitler de değişkenler gibi değer alır. Fakat adından da anlaşılabileceği üzere verilen değer daha sonradan değiştirilemez. 4 | 5 | Sabitler tanımlanırken başına const eklenir. Örnek olarak; 6 | 7 | ```go 8 | const isim string = “Ali” 9 | const isim=”Veli” 10 | ``` 11 | 12 | {% hint style="danger" %} 13 | **const** ile **:=** beraber kullanılamaz. 14 | 15 | Yanlış kullanım: **const isim := “Ali”** 16 | 17 | Doğru kullanım: **const isim = “Ali”** 18 | {% endhint %} 19 | 20 | Örnek olarak bir sabitin değerini atandıktan sonra değiştirmeye çalışalım. Aramızda ne olacağını merak eden çılgınlar olabilir. 21 | 22 | Bu şekilde yazıp kodlarımızı derlediğimizde hata almamız kaçınamaz. Derlediğimizde **cannot assign to isim** hatasını verecektir. Yani diyor ki **isim’e atanamıyor**. 23 | 24 | ```go 25 | const isim string = “Ali” 26 | isim = “Ali” 27 | const yas = 20 28 | ``` 29 | -------------------------------------------------------------------------------- /boeluem-1/tuer-doenuesuemue.md: -------------------------------------------------------------------------------- 1 | # Tür Dönüşümü 2 | 3 | Tür dönüşümü şu şekilde gerçekleştirilir. 4 | 5 | **`tür(değer)`** 6 | 7 | Örnek olarak bakmak gerekir ise; 8 | 9 | ```go 10 | i := 42 11 | f := float64(i) 12 | u := uint(f) 13 | ``` 14 | 15 | Yukarıdaki yapılan işlemleri açıklayacak olursak eğer, **i** adında bir `int` değişken tanımladık. **f** adındaki değişkende **i** değişkenini `float64` türüne dönüştürdük. **u** adındaki değişkende ise **f** değişkenini `uint` türüne çevirdik. 16 | 17 | Tüm türler arasında bu şekilde dönüşüm gerçekleştiremezsiniz. Bir sayıyı string tipine dönüştürmek istediğimizde ne olacağına bakalım. 18 | 19 | ```go 20 | deneme := string(8378) 21 | fmt.Println(deneme) 22 | ``` 23 | 24 | **deneme** adındaki değişkenimizin içinde **8378** sayısını **string** türüne dönüştürdük ve hemen aşağısına **deneme**’nin aldığı değeri ekrana bastırması için kodumuzu yazdık. 25 | 26 | Aldığımız konsol çıktısı şu şekilde olacaktır. 27 | 28 | > ₺ 29 | 30 | Yani Türk Lirası simgesi çıkacaktır. Sayılar string türüne dönüştürüldüğünde karakter olarak değer alır. 31 | -------------------------------------------------------------------------------- /boeluem-1/veri-tipleri.md: -------------------------------------------------------------------------------- 1 | # Veri Tipleri 2 | 3 | **Integer Türler** 4 | 5 | Öncelikle tüm integer türleri bir görelim; 6 | 7 | int, int8, int16, int32, int64 8 | 9 | uint, uint8, uint16, uint32, uint64, uintptr 10 | 11 | Bu veri tipleri içerisinde sayısal değerleri depolayabiliriz. Fakat şunu da unutmamalıyız. Her sayısal veri tipinin depolayabildiği maksimum bit vardır. Örnek olarak uint8 veri tipinin maksimum uzunluğu 8 bit’tir. Bitler 0 ve 1 sayılarından oluşur. 8 bit demek 8 haneli 1 ve 0 sayısı demektir. Int8 maksimum alabileceği sayı derken 11111111 (8 tane 1), yani onluk sistemde 255 sayısına denk gelir. int 8 ise pozitif olarak +127, negatif olarak -128 maksimum değerinin alabilir. (127+128=255). int16 +32767 ve -32768 maksimum değerlerini alır. Int32 +2147483647 ve -2147483648 maksimum değerlerini alır. Int64 +9223372036854775807 ve -9223372036854775808 maksimum değerini alır. 12 | 13 | U harfi ile başlayan sayı veritiplerinde ise sayının değeri pozitif veya negatif işarette değildir. Sadece bir sayısal değerdir. U’nun anlamı unassigned yani işaretsizdir. Uint8 0-255 arası, uint16 0-65535, uint32 0-42967295 arası, uint64 0-18446744073709551615 arası değerler alabilir. Uintptr ise yazdığınız sayıya göre alanı belirlenir. 14 | 15 | Integer sayısal veri tipleri içierisinden bahsedebileceğimiz son tipler ise int ve uint. Int ve uint veri tipleri kullanmış olduğumuz işletim sistemi 32bit ise 32bit değer alırlar, 64bit ise 64bit değer alırlar. Sayısal bir değer atanacağı zaman en çok kullanılan veri tipleridir. Genellikle int daha çok kullanılır. Eğer çok meşakkatli bir program yazmayacaksanız int kullanmanız önerilir. 16 | 17 | **Byte Veri Tipi:** uint8 ile aynıdır. 18 | 19 | **Rune:** int32 ile aynıdır. Unicode karakter kodlarını ifade eder. 20 | 21 | **Float Türler** 22 | 23 | Float türleri integer türlerden farklı olarak küsüratlı sayıları tutar. Örnek: 3.14 24 | 25 | **Lütfen Dikkat!** 26 | 27 | Küsüratlı sayılar İngiliz-Amerikan sayı sistemine göre nokta koyarak ifade edilir. Türk sistemindeki gibi virgül (3,14) ile ifade edilmez. 28 | 29 | **float32:** 32bitlik değer alabilir. 30 | 31 | **float64:** 64 değer alabilir. 32 | 33 | **Complex Türler** 34 | 35 | Complex türleri içerisinde gerçel küsüratlı (float) ve sanal sayılar barındırabilir. Türkçe’de karmaşık sayılar diye adlandırılır. 36 | 37 | **complex64:** Gerçel float32 ve sanal sayı değeri barındırır. 38 | 39 | **complex128:** Gerçel float64 ve sanal sayı değeri barındırır. 40 | 41 | Sayısal türler bu şekildedir. 42 | 43 | **BOOLEAN VERİ TİPİ** 44 | 45 | Boolean yani mantıksal veri tipi bir durumun var olması halinde olumlu (true) değer, var olmaması halinde olumsuz (false) değer alan veri tipidir. 46 | 47 | **STRING VERİ TİPİ** 48 | 49 | String yani dizgi veri tipi içerisinde metinsel ifadeler barındırır. Örnek olarak “Golang çok güzel ama ingilicce”. String veri tipi değeri çift tırnak ( “Değer” ) içine yazılır. Diğer dillerdeki gibi tek tırnak ( ‘Değer’ ) insiyatifi yoktur. Tek tırnakla kullanım başka bir amaç içindir. İlerde onu da göstereceğim. 50 | 51 | **Özet olarak Veri Tipleri** 52 | 53 | Veri tipleri atanacak değerlerimizi RAM üzerinde depolamak için kullandığımız araçlardır. Tam sayı değerler için Integer veri tiplerini, ondalık sayılar için Float veri tiplerini, mantıksal değerler için Boolean veri tipini, metinsel değerler için String veri tipini kullanırız. Karmaşık sayı değerleri için ise Complex veri tipini kullanırız. 54 | 55 | ”Türkiye” = String Tipi 56 | 57 | 1881 = Integer Tipi 58 | 59 | 10,5 = Float Tipi 60 | 61 | True = Boolean Tipi 62 | 63 | 2+3i = Complex Tipi 64 | 65 | **Veri Tiplerinin Varsayılan Değerleri** 66 | 67 | Veri tipleri içerisine değer atanmadan oluşturulduğu zaman varsayılan bir değer alır. 68 | 69 | Sayısal Tipler için 0, 70 | 71 | Boolean Tipi için false, 72 | 73 | String Tipi için “” (Boş dizgi) değeri alır. 74 | -------------------------------------------------------------------------------- /boeluem-1/vscode-varsayilan-hata-ayiklayiciyi-secme.md: -------------------------------------------------------------------------------- 1 | # VSCode Varsayılan Hata Ayıklayıcıyı Seçme 2 | 3 | VSCode Go programlama yapıyorken, **F5** tuşuna bastığınızda üst tarafta hata ayıklayıcıyı seçmenizi ister. Her **F5** tuşuna bastığınızda hata ayıklayıcı seçim ekranı çıksın istemiyorsanız, yani herzaman bir hata ayıklayıcıyı kullansız istiyorsanız, yapacaklarınız çok basit. 4 | 5 | VSCode üzerinde ekranın sol tarafından **Run** sekmesine geçelim. 6 | 7 | ![Adım.1](../.gitbook/assets/image.png) 8 | 9 | Biz varsayılan olarak **Go Hata Ayıklayıcısı**'nı seçeceğiz. 10 | 11 | **Go**'yu varsayılan hale getirmek içinse, ekranın solundan `create a launch.json file` bağlantısına tıklayalım. 12 | 13 | ![Adım.2](../.gitbook/assets/defaultdebugger2.png) 14 | 15 | Üst tarafta açılan ekrandan **Go**'yu seçelim. 16 | 17 | ![Adım.3](../.gitbook/assets/defaultdebugger1.png) 18 | 19 | Seçtikten sonra VSCode bizim için `launch.json` adında bir dosya oluşturacak. Bu dosya **F5** tuşuna bastığımızda gerçekleşecek olayları barındıryor. Dikkat edeceğimiz nokta **type** bölümünde **go** yazıyor olması. 20 | 21 | ![Adım.4](../.gitbook/assets/defaultdebugger3.png) 22 | 23 | Daha sonra `launch.json` dosyamızı kaydedip kapatabiliriz. 24 | 25 | Bir sonra hata ayıklama işleminde **Go** otomatik çalışacaktır. 26 | -------------------------------------------------------------------------------- /boeluem-1/yorum-satiri.md: -------------------------------------------------------------------------------- 1 | # Yorum Satırı 2 | 3 | Diğer dillerde de olduğu gibi Golang’ta yorum satırı özelliği mevcuttur. Yorum satırı derleyici tarafından işlenmez. Yani görmezden gelinir. Bu bölüme kendiniz için açıklama vs. bilgiler yazabilirsiniz. Golang’ta yorum satırı oluşturmak için 2 yöntem mevcuttur. 4 | 5 | **// Çift Taksim Yöntemi** 6 | 7 | Bu yöntem ile derlenmesini istemediğimiz yazının başına çift taksim ekleyerek görmezden gelinmesini sağlıyoruz. 8 | 9 | ```go 10 | //Buraya herhangi birşey yazabilirsiniz 11 | ``` 12 | 13 | **/\* \*/ Taksim-Yıldız Yöntemi** 14 | 15 | Bu yöntem ile birden fazla satırın derlemede görmezden gelinmesini sağlayabiliriz. 16 | 17 | ```go 18 | /* Buraya 19 | herhangi 20 | birşey 21 | yazabilirsiniz */ 22 | ``` 23 | -------------------------------------------------------------------------------- /boeluem-2/anonim-fonksiyonlar.md: -------------------------------------------------------------------------------- 1 | # Anonim Fonksiyonlar 2 | 3 | Anonim fonksiyonların en büyük özelliği isimsiz olmalarıdır. (Zaten adından da belli oluyor 🤔) Yazıldıkları yerde direkt olarak çalışırlar. Çalışırken diğer fonksiyonlardaki gibi parametre verilemediği için fonksiyonun sonuna parametre eklenerek çalışıtırılırlar. Örneğimizi görelim: 4 | 5 | ```go 6 | package main 7 | 8 | import "fmt" 9 | 10 | func main() { 11 | metin := "Merhaba Dünya" 12 | 13 | func(a string) { 14 | fmt.Println(a) 15 | }(metin) 16 | } 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /boeluem-2/bos-tanimlayicilar.md: -------------------------------------------------------------------------------- 1 | # Boş Tanımlayıcılar 2 | 3 | Golang kodlarımızda bazen 2 adet değer döndüren fonksiyonlar kullanırız. Bu değerlerden hangisini kullanmak istemiyorsak, değişken adı yerine **\_ (alt tire)** kullanırız. 4 | 5 | Örneğimizi görelim: 6 | 7 | ```go 8 | package main 9 | 10 | import "fmt" 11 | 12 | func fonksiyonumuz(girdi int) (int, int) { 13 | işlem1 := girdi / 2 14 | işlem2 := girdi / 4 15 | return işlem1, işlem2 16 | } 17 | 18 | func main() { 19 | ikiyeböl, dördeböl := fonksiyonumuz(16) 20 | fmt.Println(ikiyeböl, dördeböl) 21 | } 22 | ``` 23 | 24 | Gördüğünüz gibi fonksiyonumuzdan dönen iki değeri de değişkenlere atadık. Eğer birini atamak istemeseydik şöyle yapardık: 25 | 26 | ```go 27 | package main 28 | 29 | import "fmt" 30 | 31 | func fonksiyonumuz(girdi int) (int, int) { 32 | işlem1 := girdi / 2 33 | işlem2 := girdi / 4 34 | return işlem1, işlem2 35 | } 36 | 37 | func main() { 38 | ikiyeböl, _ := fonksiyonumuz(16) 39 | fmt.Println(ikiyeböl) 40 | } 41 | ``` 42 | 43 | Yukarıdaki kodlarımızda fonksiyonumuzun 4’e bölme özelliğini kullanmak istemediğimizden dolayı boş tanımlama işlemi yaptık. 44 | 45 | Boş tanımlama işlemleri çoğunlukla Golang’ta programcılar tarafından hata çıktısını kullanmak istenmediğinizde yapılıyor. 46 | -------------------------------------------------------------------------------- /boeluem-2/defer.md: -------------------------------------------------------------------------------- 1 | # Defer 2 | 3 | Defer kelimesinin Türkçe’deki karşılığı **ertelemektir**. Bu deyimi yapacağımız işlemin başına eklersek o işlemi içerisinde bulunduğu fonksiyonun içindeki işlemlerden sonra çalıştırır. Çok karışık bir cümle kurdum ama uygulamaya geçince anlayacaksınız. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func main() { 9 |  defer fmt.Println("İlk Cümle") 10 |  fmt.Println("İkinci Cümle") 11 | } 12 | ``` 13 | 14 | Çıktımız şu şekilde olacaktır; 15 | 16 | > İkinci Cümle 17 | > 18 | > İlk Cümle 19 | 20 | Açıklamaya gelirsek ekrana **İlk Cümle** yazısını bastıran satırımızın başına **defer** terimini ekledik. **defer** eklediğimiz satır **main()** fonksiyonunun içinde olduğu için **main()** fonsyionundaki tüm işlemler tamamlandıktan sonra ekrana yazımızı bastırdı.\ 21 | Birden fazla defer ekleyecek olursak; 22 | 23 | ```go 24 | package main 25 | import "fmt" 26 | func main() { 27 |  defer fmt.Println("ilk Cümle") 28 |  defer fmt.Println("İkinci Cümle") 29 |  defer fmt.Println("Üçüncü Cümle") 30 |  defer fmt.Println("Dördüncü Cümle") 31 |  fmt.Println("Beşinci Cümle") 32 | } 33 | ``` 34 | 35 | Çıktımız şu şekilde olacaktır; 36 | 37 | > Beşinci Cümle 38 | > 39 | > Dördüncü Cümle 40 | > 41 | > Üçüncü Cümle 42 | > 43 | > İkinci Cümle 44 | > 45 | > ilk Cümle 46 | 47 | Burdan anlıyoruz ki en baştaki defer eklenen satır en son işleme tabi tutuluyor. Hadi defer ile alakalı bir programlama alıştırması yapalım. 48 | 49 | ```go 50 | package main 51 | import "fmt" 52 | func main() { 53 |  fmt.Println("Sayıyor") 54 |  for i := 0; i < 10; i++ { 55 |   defer fmt.Println(i) 56 |  } 57 |  fmt.Println("Bitti") 58 | } 59 | ``` 60 | 61 | Çıktımız şöyle olacaktır; 62 | 63 | > Sayıyor 64 | > 65 | > Bitti 66 | > 67 | > 9 68 | > 69 | > 8 70 | > 71 | > 7 72 | > 73 | > 6 74 | > 75 | > 5 76 | > 77 | > 4 78 | > 79 | > 3 80 | > 81 | > 2 82 | > 83 | > 1 84 | > 85 | > 0 86 | -------------------------------------------------------------------------------- /boeluem-2/doengueler.md: -------------------------------------------------------------------------------- 1 | # Döngüler 2 | 3 | Programlama ile uğraşan arkadaşlarımızın da bileceği üzere, programlama dillerinde **while, do while** ve **for** döngüleri vardır. Bu döngüler ile yapacağımız işlemin belirli koşullarda tekrarlanmasını sağlayabiliriz. Golang’ta ise diğer dillerin aksine sadece **for** döngüsü vardır. Ama bu **while** ve **do while** ile yapılanları yapamayacağımız anlamına gelmiyor. Golang’taki for döngüsü ile hepsini yapabiliriz. Yani dilin yapımcıları tek döngü komutu ile hepsini yapabilmemize olanak sağlamışlar. 4 | 5 | Gelelim for döngüsünün kullanımına. Go’da for döngüsü parametreleri parantez içine alınmaz. 6 | 7 | **STANDART FOR KULLANIMI** 8 | 9 | ```go 10 | package main 11 | 12 | import "fmt" 13 | 14 | func main() { 15 | for i := 0; i < 10; i++ { 16 | fmt.Println(i) 17 | } 18 | } 19 | ``` 20 | 21 | **Açıklaması:** 22 | 23 | **For** döngüsünden ayrı olarak **deger** adında **0** sayısal değerini alan bir değişken oluşturduk. **For** döngüsünde ise sadece koşul parametresini belirttlik. Yani döngü **deger** değişkeni **10** sayısından küçük olduğu zaman çalışacak. **For** kod bloğu içerisinde her döngü tekrarlandığında deger değişkeni ekrana basılacak ve deger değişkenine **+1** eklenecek. 24 | 25 | Konsol çıktımız şu şekilde olacaktır; 26 | 27 | > 0 28 | > 29 | > 1 30 | > 31 | > 2 32 | > 33 | > 3 34 | > 35 | > 4 36 | > 37 | > 5 38 | > 39 | > 6 40 | > 41 | > 7 42 | > 43 | > 8 44 | > 45 | > 9 46 | 47 | **SADECE KOŞUL BELİRTEREK KULLANMA** 48 | 49 | Bu **for** yazım şekli while mantığı gibi çalışır. Parametrelerde sadece koşul belirtilir. 50 | 51 | ```go 52 | package main 53 | 54 | import "fmt" 55 | 56 | func main() { 57 | deger := 0 58 | for deger < 10 { 59 | fmt.Println(deger) 60 | deger++ 61 | } 62 | } 63 | ``` 64 | 65 | **Açıklaması:** 66 | 67 | **For** döngüsünden ayrı olarak **deger** adında **0** sayısal değerini alan bir değişken oluşturduk. **For** döngüsünde ise sadece koşul parametresini belirttlik. Yani döngü **deger** değişkeni **10** sayısından küçük olduğu zaman çalışacak. **For** kod bloğu içerisinde her döngü tekrarlandığında deger değişkeni ekrana basılacak ve deger değişkenine **+1** eklenecek. 68 | 69 | Konsol çıktımız şu şekilde olacaktır; 70 | 71 | > 0 72 | > 73 | > 1 74 | > 75 | > 2 76 | > 77 | > 3 78 | > 79 | > 4 80 | > 81 | > 5 82 | > 83 | > 6 84 | > 85 | > 7 86 | > 87 | > 8 88 | > 89 | > 9 90 | -------------------------------------------------------------------------------- /boeluem-2/fonksiyon-cesitleri.md: -------------------------------------------------------------------------------- 1 | # Fonksiyon Çeşitleri 2 | 3 | Golang’ta genel olarak 3 çeşit fonksiyon yapısı bulunmaktadır. Hemen bu çeşitleri görelim. 4 | 5 | **Variadic Fonksiyonlar** 6 | 7 | Variadic fonksiyon tipi ile fonksiyonumuza kaç tane değer girişi olduğunu belirtmeden istediğiniz kadar değer girebilirsiniz. 8 | 9 | Hemen örneğimize geçelim. 10 | 11 | ```go 12 | package main 13 | 14 | import "fmt" 15 | 16 | func toplama(sayilar ...int) int { 17 | toplam := 0 18 | for _, n := range sayilar { 19 | toplam += n 20 | } 21 | return toplam 22 | } 23 | 24 | func main() { 25 | fmt.Println(toplama(3, 4, 5, 6)) //18 26 | } 27 | ``` 28 | 29 | Yukarıdaki fonksiyonumuzu inceleyelim. Vereceğimiz sayıları toplaması için aşağıda **toplama** adında bir fonksiyon oluşturduk. Fonksiyonun parametresi içerisine, yani parantezler içerisine, **sayilar** isminde **int** tipinde bir değişken tanımladık. **…** (üç nokta) ile istediğimiz kadar değer alabileceğini belirttik. **toplam** değerini mantıken doğru değer vermesi için **0** yaptık. Çünkü her sayıyı toplam değikeninin üzerine ekleyecek. 30 | 31 | **range**’in buradaki kullanım amacından bahsedeyim. **range**’i **for** döngüsü ile kullandığımızda işlem yaptığımız öğenin uzunluğuna göre işlemimizi sürdürürüz. Yani fonksiyonumuzun içine ne kadar sayı eklersek işlemimiz ona göre şekillenecektir. For ve Range işlemini daha sonraki bölümümüzde göreceğiz. 32 | 33 | **Range** kullanımında **\_, n** şeklinde değişken tanımlamamızın sebebi, birinci değişken yani **\_**, dizinin indeksini yani sıra numarasını verir. Bizim bununla bir işimiz olmadığı için **\_** koyarak kullanmayacağımızı belirttik. İkinci değişken ise yani **n** dizinin içindeki değeri verir yani fonksiyona girdiğimiz sayıları. Sonuç olarak bu fonksiyonda **return** ile **for** işleminden sonra tüm sayıların toplamını döndürüp **main()** fonksiyonu içerisinde ekrana bastırmış olduk. 34 | 35 | **Closure (Atanmış) Fonksiyonlar** 36 | 37 | Closure fonksiyonlar ile değişkenlerimizi fonksiyon olarak tanımlayabiliriz. Buradan anlamamız gereken şey fonksiyonların da atanabilen veri tipleri olduğudur. Örneğimize geçelim. 38 | 39 | ```go 40 | package main 41 | 42 | import "fmt" 43 | 44 | func main() { 45 | toplam := func(x, y int) int { 46 | return x + y 47 | } 48 | fmt.Println(toplam(2, 3)) 49 | } 50 | ``` 51 | 52 | Yukarıdaki kodlarımızı inceleyecek olursak, **main** fonksiyonunun içine **toplam** adında bir değişken oluşturduk. Bu değişkenin türünün otomatik algılanması için **:=** işaretlerimizi girdik. Değişkene değer olarak anonim bir fonksiyon (ismi olmayan fonksiyon yani) yazdık. Bu fonksiyon **x** ve **y** adında iki tane **int** değer alıyor ve **return** kısmında bu iki değeri **int** olarak döndürüyor. Aşağıdaki **Println()** fonksiyonunda ise bu değişkeni aynı bir fonksiyonmuşcasına kullandık. 53 | 54 | Atanmış fonksiyonlar yöntemine benzer olarak, bir fonksiyon ile fonksiyon tipinde veri döndürerek de atayabiliriz. 55 | 56 | ```go 57 | package main 58 | 59 | import "fmt" 60 | 61 | func main() { 62 | p := yazdır() 63 | 64 | p("Merhaba Dünya") 65 | 66 | } 67 | 68 | func yazdır() func(s string) { 69 | return func(s string) { 70 | fmt.Println(s) 71 | } 72 | } 73 | ``` 74 | 75 | **Recursive (Özyinelemeli) Fonksiyonlar** 76 | 77 | Recursive fonksiyonlar yazdığımız fonksiyonun içinde aynı fonksiyonu kullanmamız demektir. Fonksiyonumun tüm işlemler bittiğinde return olur. Örneğimize geçelim. 78 | 79 | ```go 80 | package main 81 | 82 | import "fmt" 83 | 84 | func main() { 85 | fmt.Println(faktoriyel(4)) 86 | } 87 | 88 | func faktoriyel(a uint) uint { 89 | if a == 0 { 90 | return 1 91 | } 92 | return a * faktoriyel(a-1) 93 | } 94 | ``` 95 | 96 | Yukarıdaki fonksiyon ile bir sayının faktöriyelini hesaplayabiliriz. Faktöriyel hakkında kısaca bir hatırlatma yapayım. Belirlediğimiz sayıya kadar olan tüm sayıların sırasıyla çarpımınına o sayının faktöriyeli denir. Yani 4 sayısının faktöriyelini bulmak istiyorsak: 1\_2\_3\*4 işlemini yaparız. Sonuç 24’tür. 97 | 98 | Faktöriyel fonksiyonun giriş ve çıkış tiplerini uint yapmamızın sebebi ise faktöriyel sonucunu bulmak için en geriye gidildiğinde eksi değerlere geçilmemesi içindir. Ayrıca sıfırın faktöriyeli birdir. Onun için değer sıfırsa bir return etmesini istedik. Faktöriyel fonksiyonunun en alttaki return kısmında girdiğimiz sayı ile girdiğimiz sayının bir eksiğinin faktöriyelini çarpacak. Girdiğimiz sayının bir küçüğünü bulmak içinse yeniden o sayının faktöriyelini hesaplayacak. Daha sonra aynı işlemler bu sayılar içinde yapılacak, ta ki sayı sona gelene yani en küçük uint değeri olan 0’a dayanana kadar. Daha sonra sonucu main fonksiyonu içerisinde ekrana bastırdık. 99 | -------------------------------------------------------------------------------- /boeluem-2/fonksiyonlar.md: -------------------------------------------------------------------------------- 1 | # Fonksiyonlar 2 | 3 | Fonksiyonlar içlerine parametre girilebilen ve işlemler yapabilen birimlerdir. Matematikteki fonksiyonlar ile aynı mantıkta çalışan bu birimlerden bir örneği inceleyelim. 4 | 5 | ```go 6 | package main 7 | 8 | import "fmt" 9 | 10 | func topla(a int, b int) int { 11 | return a + b //a ve b’nin toplamını döndürür. 12 | } 13 | 14 | func main() { 15 | fmt.Println(topla(2, 5)) //2+5 sonucunu ekrana bastır 16 | } 17 | ``` 18 | 19 | Yukarıdaki kodları ineleyecek olursak, foksiyonlarımızı oluşturmak için **func** anahtar kelimesini kullanırız. Yanına ise fonskiyonumuzun ismini yazarız. Parantez içine fonksiyonumuzun dışarıdan alacağı parametreler için değişken-tip tanımlaması yaparız. parantezin sağına ise fonksiyonun döndüreceği **return** değerinin tipini yazarız. Süslü parantezler içinde fonksiyonumuzun işlemleri bulunur. Son olarak return ile veri tipini belirlediğimiz değeri elde etmiş oluruz. 20 | 21 | **Main** fonksiyonu içerisinde **topla(2,5)** fonksiyonu ile 2 ve 5 sayısının toplamını ekrana bastırmış olduk. Yani ekrana 7 sayısı verildi. 22 | 23 | Fonksiyonlar istendiği kadar parametre alabildiği gibi, istenirse parametresiz de olabilir. Fonksiyonları veri return etmek yerine bir işlem yaptırmak içinde kullanabiliriz. 24 | 25 | ```go 26 | package main 27 | 28 | import "fmt" 29 | 30 | func yazdir() { 31 | fmt.Println("yazı yazdırdık") 32 | } 33 | 34 | func main() { 35 | yazdir() 36 | } 37 | ``` 38 | 39 | **yazdir** adlı fonsiyonumuzun parantezine değişken tanımlamadık ve parantezin sağına fonksiyon bloğu içerisinde **return** olmadığı için veri çıkış tipini belirtmedik. Fonksiyonumuzun içerisinde sadece ekrana yazı bastırdık. 40 | 41 | **Fonksiyonlar Hakkında Ayrıntılı Bilgiler** 42 | 43 | Fonksiyon parantezi içerisine değişken tanımlanırken eğer tüm değişkenlerin türleri aynı ise sadece en sağdaki değişkenin tipini belirtmeniz yeterlidir. Örnek: 44 | 45 | ```go 46 | package main 47 | 48 | import "fmt" 49 | 50 | func islem(sayi int) (x, y int) { //return’un degiskenlerini tanımladık 51 | x = sayi / 2 52 | y = sayi * 2 53 | return //Burada sadece return yazıyor 54 | } 55 | 56 | func main() { 57 | fmt.Println(islem(10)) 58 | } 59 | ``` 60 | 61 | Yukarıda ise isimlendirilmiş **return** kullandık. return tipini yazdığımız paranteze bakacak olursa **(x, y int)** diyerek **return** edilecek verinin fonksiyonun blokları içerisinden çekilmesini sağladık. Böylece fonksiyon bloğununun sonundaki **return** kelimesinin yanına birşey yazmadık. Bu fonksiyonumuzun çıktısı ise **5 20** olacaktır. 62 | -------------------------------------------------------------------------------- /boeluem-2/if-else.md: -------------------------------------------------------------------------------- 1 | # If-Else 2 | 3 | If ve Else kelimelerinin Türkçe karşılığına bakacak olursak; 4 | 5 | **If :** Eğer, **Else :** Yoksa anlamına gelir. **If-Else** akışı koşullandırmalar için kullanılır. Diğer dillerin aksine koşul parametresi parantezler içine yazılmaz. Teorik kısmı bırakıp uygulama kısmına geçelim ki daha anlaşılır olsun 6 | 7 | ```go 8 | if koşul { 9 | //Koşul sağlandığında yapılacak işlemler 10 | } else { 11 | //Koşul sağlanmadığında yapılacak işlemler 12 | } 13 | ``` 14 | 15 | Yukarıdaki kod tanımına göre örnek bir program yazalım; 16 | 17 | ```go 18 | package main 19 | 20 | import "fmt" 21 | 22 | func main() { 23 |  i := 5 24 |  if i == 5 { 25 |   fmt.Println("i'nin değeri 5'tir.") 26 |  } else { 27 |   fmt.Println("i'nin değeri 5 değildir.") 28 |  } 29 | } 30 | ``` 31 | 32 | Yukarıdaki kodları inceleyelim. i’nin değerini 5 verdik. `if` teriminin sağında i’nin 5 eşitliği koşulunu sorguladık. Eşitse ekrana "i’nin değeri 5’tir." yazısını bastıracak. Değilse "i’nin değeri 5 değildir." yazısı bastıracak. Bu yüzden i’nin değeri 5 olduğu için ekrana "i’nin değeri 5’tir." yazısını bastırdı. If-Else akşında else kullanmamamız else’nin kod bloğunu boş bırakmamız ile aynı anlama gelir. 33 | 34 | ```go 35 | i := 10 36 | if i==10 { 37 |  fmt.Println(“i’nin değeri 10’dur.”) 38 | } 39 | ``` 40 | 41 | Yukarıda sadece **if** deyimini girdik. **Else**’yi girmedik. Burada sonuçlanan olay, **i**’nin değeri **10**’a eşitse **i**’nin değeri **10**’dur. yazısını ekrana bastırır. **Else** deyimini girmediğimiz için şartın sağlanmaması durumunda hiçbir işlem gerçekleşmez. Çıktımız **i**’nin değeri **10**’a eşit olduğu için **i**’nin değeri **10**’dur. çıkar. 42 | 43 | **ELSE-IF KULLANIMI** 44 | 45 | **If-Else** akışında birden fazla koşul kontrolü ekleyebiliriz. Bunu **else if** deyimi ile yapabiliriz. Kısaca bakacak olursak; 46 | 47 | ```go 48 | i := 5 49 | if i == 5 { 50 |  fmt.Println("i'nin değeri 5'tir.") 51 | } else if i==3{ 52 |  fmt.Println("i'nin değeri 3'tür.") 53 | }else{ 54 |  fmt.Println("i'nin değeri belirsiz.") 55 | } 56 | ``` 57 | 58 | else if deyiminin yazılışını da gördük. Açıklamaya gelirsek, else if deyimi kendinden önceki deyimin koşulunun sağlanmaması halinde bir sonraki koşulu kontrol ettirir. If-Else akışında istenildiği kadar else if deyimi eklenebilir. 59 | 60 | \ 61 | **Koşullar İçerisinde Operatör Kullanımı**\ 62 | Koşullar içerisinden mantıksal ve ilişkisel operatörler kullanılabilir. Operatörleri görmüştük. Operatör kullanarak örnekler yapalım. 63 | 64 | ```go 65 | package main 66 | import "fmt" 67 | func main() { 68 |  i := 5 69 |  a := 3 70 |  b := 5 71 |  if i != a { //Birinci Koşul 72 |   fmt.Println("i eşit değildir a") 73 |  } 74 |  if i == b { //İkinci Koşul 75 |   fmt.Println("i eşittir b") 76 |  } 77 |  if i == b && i > a { //Üçüncü Koşul 78 |   fmt.Println("i eşittir b ve i büyüktür a") 79 |  } 80 | } 81 | ``` 82 | 83 | Çıktımız şu şekilde olacaktır; 84 | 85 | > i eşit değildir a 86 | > 87 | > i eşittir b 88 | > 89 | > i eşittir b ve i büyüktür a 90 | -------------------------------------------------------------------------------- /boeluem-2/pointers-isaretciler.md: -------------------------------------------------------------------------------- 1 | # Pointers (İşaretçiler) 2 | 3 | İşaretçiler ile nesnenin bellekteki adresi üzerinden işlemler yapabilir. Daha önceden işaretçileri içeren bir dil kullanmamış veya herhangi bir programlama dili de kullanmamış olabilirsiniz. Bu yüzden daha iyi anlamanız için işaretçilerin çalışma mantığını bilmemiz gerekir. 4 | 5 | Örnek olarak `a` isminde bir değişkenimiz olsun. Bu değişkenimiz `tam sayı (int)` tipinde `8` değerini saklıyor olsun. Bu da Go dilinde aşağıdaki gibi oluyor. 6 | 7 | ```go 8 | var a int = 8 9 | ``` 10 | 11 | Bu değişkenimizi oluşturduktan sonra programımız çalışmaya başlayınca işletim sistemimiz bu değişkene özel, **bellek (RAM)** üzerinde bir alan ayıracaktır. Programın geri kalanında değişkenimizin değerine bu alan üzerinden ulaşılacaktır. Yani bir değişken oluşturduğumuzda bellek üzerinde aşağıdaki resimdeki gibi bir alan oluştuğunu hayal edebilirsiniz. 12 | 13 | ![Değişkenin RAM üzerindeki Alanı (Temsili)](../.gitbook/assets/pointeronram.png) 14 | 15 | Yukarıdaki resimde mor renkli olarak gördüğümüz ifade ise değişkenimizin bellekteki adresidir. (Bu adres temsilidir. Zaten sürekli olarak değişen birşeydir.) 16 | 17 | ## Peki Go'da işaretçileri nasıl kullanırız? 18 | 19 | Bir program senaryosu belirleyelim. Bu programımızda yukarıdaki gibi `a` isminde `int` tipinde `8` değerini tutan bir değişkenimiz olsun. Ve `a` değişkenimize `5` ekleyen bir fonksiyonumuz olsun. Son olarak `a`'yı ekrana bastıralım. 20 | 21 | ```go 22 | package main 23 | 24 | import "fmt" 25 | 26 | func main() { 27 | a := 8 28 | ekle(a) 29 | fmt.Println(a) 30 | //sonucumuz yine 8 olacak 31 | } 32 | func ekle(v int) { 33 | v += 5 34 | } 35 | ``` 36 | 37 | Yukarıdaki örnekte `a` değişkenini ekrana bastırdığımızda sonucun hala `8` olduğunu görüyoruz. Halbuki `ekle` fonksiyonunun içerisinde gördüğümün gibi `5` ekliyoruz. 38 | 39 | `a` değişkeninin değişmeme sebebi şudur:\ 40 | `ekle` fonksiyonunun parametresi olarak `int` tipinde `v` değişkenini oluşturduk. `v` değişkenimiz aslında `a`'dan gelen değeri kullanmamızı sağlıyor. Yani bize `a`'nın kendisini vermiyor. O yüzden `v` üzerinde değişiklik yaptığımızda `a`'ya yansımayacaktır. 41 | 42 | `a` değişkenini değiştirebilmemiz için bize `a`'nın bellekteki adresi gerekiyor. Bunun için de `&` (ampersand) işaretini kullanabiliriz. 43 | 44 | ![Ampersand kullanımı](../.gitbook/assets/ampkullanımı.png) 45 | 46 | Örnek vermek gerekirse: 47 | 48 | ```go 49 | func main() { 50 | a := 8 51 | fmt.Println(&a) //Çıktımız: 0xc0000b8010 52 | } 53 | ``` 54 | 55 | Artık `a`'nın bellekteki adresini öğrenebiliyoruz. Sıra geldi bu adres üzerinden `a`'nın değerine ulaşabilmeye. 56 | 57 | Bunun için de `*` (yıldız) işaretini kullanabiliriz. 58 | 59 | ```go 60 | func main() { 61 | a := 8 62 | fmt.Println(&a) //Çıktımız: 0xc0000b8010 63 | b := &a 64 | fmt.Println(b) //Çıktımız: 0xc0000b8010 65 | fmt.Println(*b) //Çıktımız: 8 66 | } 67 | ``` 68 | 69 | Yukarıdaki örneği incelediğimizde `b` değişkenine `a`'nın adresini atadık. `b`'yi bastırdığımızda `a`'nın bellekteki adresini görebiliriz. Aynı zamanda `*b` şeklinde kullanarak `a`'nın içindeki değere de ulaşabiliriz. Bu durumda a ve bdeğişkenleri aynı bellek alanını temsil ediyorlar. 70 | 71 | `a` değişkenine `b` üzerinden değişiklik yapmak için aşağıdaki yöntemi uygulayabilirsiniz. 72 | 73 | ```go 74 | package main 75 | 76 | import "fmt" 77 | 78 | func main() { 79 | a := 8 80 | b := &a 81 | *b = 10 82 | fmt.Println(a) //10 83 | } 84 | ``` 85 | 86 | En başta kurguladığımız senaryoyu işaretçiler ile kolayca yapabiliriz. 87 | 88 | ```go 89 | package main 90 | 91 | import "fmt" 92 | 93 | func main() { 94 | a := 8 95 | ekle(&a) 96 | fmt.Println(a) //Çıktımız: 13 97 | } 98 | func ekle(v *int) { 99 | *v += 5 100 | } 101 | ``` 102 | 103 | Yukarıdaki örneği incelediğimizde, `ekle` fonksiyonumuzu oluştururken parametre olarak verdiğimiz `v` değişkeninin tipinde önce `*` işareti koyduk. Bunun sebebi `v` değişkeni ile fonksiyonumuza gelecek olan adresin içindeki değere ulaşabilmektir. 104 | 105 | `ekle` fonksiyonunun içerisindeki `v`'yi kullanırken de başına `*` koyarak kullandık. 106 | 107 | `main` fonksiyonumuzda `ekle` fonksiyonunu çağırırken de `a` değişkenini `&` işareti kullanarak bellekteki adresi ile verdik. 108 | 109 | Bu sayede `a` değişkenine bellekteki adresi ile müdahale etmiş olduk. 110 | -------------------------------------------------------------------------------- /boeluem-2/switch.md: -------------------------------------------------------------------------------- 1 | # Switch 2 | 3 | Switch kelimesinin Türkçe’deki anlamı **anahtardır**. Switch deyimi de if-else deyimi gibi koşul üzerine çalışır. Yine teorik kısmı geçip anlaşılır olması için örnek yapalım. **case** deyimi durumu ifade eder. Koşul sağlandığı zaman işleme devam edilmez. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func main() { 9 |  i := 5 10 |  switch i { 11 |   case 5: 12 |    fmt.Println("i eşittir 5") 13 |   case 10: 14 |    fmt.Println("i eşittir 10") 15 |   case 15: 16 |    fmt.Println("i eşittir 15") 17 |  } 18 | } 19 | ``` 20 | 21 | Çıktımız şu şekilde olacaktır; 22 | 23 | > i eşittir 5 24 | 25 | Switch’te koşulların gerçekleşmediği zaman işlem uygulamak istiyorsak bunu **default** terimi ile yaparız. Örnek; 26 | 27 | ```go 28 | i := 5 29 | switch i { 30 |  case 5: 31 |   fmt.Println("i eşittir 5") 32 |  default: 33 |   fmt.Println("i bilinmiyor") 34 | } 35 | ``` 36 | 37 | ### **Koşulsuz Switch** 38 | 39 | Switch’in tanımını daha iyi anlayabilmeniz için koşulsuz switch kullanımına örnek verelim. Bu yöntemde switch deyiminin yanına koşul girmek yerine case deyiminin yanına koşul giriyoruz. 40 | 41 | ```go 42 | package main 43 | import "fmt" 44 | func main() { 45 |  i := 5 46 |  switch { 47 |   case i == 5: //i=5 olduğu için diğer case’ler sorgulanmaz 48 |    fmt.Println("i eşittir 5") 49 |   case i < 10: 50 |    fmt.Println("i küçüktür 10") 51 |   case i > 3: 52 |    fmt.Println("i büyüktür 3") 53 |  } 54 | } 55 | ``` 56 | 57 | Çıktımız şu şekilde olacaktır; 58 | 59 | > i eşittir 5 60 | 61 | ### Sonraki Koşulu Kontrol Ettirme 62 | 63 | Durumlar içerisinde kontrol etmemiz gereken başka durumlarda olabilir. Bunun için **fallthrough** deyimini kullanabiliriz. 64 | 65 | ```go 66 | package main 67 | 68 | import "fmt" 69 | 70 | func main() { 71 | x := 5 72 | switch { 73 | case x == 5: 74 | fmt.Println("x 5'tir") 75 | fallthrough 76 | case x < 10: 77 | fmt.Println("x 10'dan küçüktür") 78 | 79 | } 80 | } 81 | ``` 82 | 83 | Çıktımız aşağıdaki gibi olacaktır. 84 | 85 | > x 5'tir\ 86 | > x 10'dan küçüktür 87 | 88 | ### Switch'e Özel Değişken Tanımlama 89 | 90 | Tıpkı If deyimindeki gibi Switch içerisinde de kullanabileceğimiz değişkenler tanımlayabiliriz. 91 | 92 | ```go 93 | switch x := 5; { 94 | case x == 5: 95 | fmt.Println("x 5'tir") 96 | case x < 10: 97 | fmt.Println("x 10'dan küçüktür") 98 | } 99 | ``` 100 | -------------------------------------------------------------------------------- /boeluem-3/anonim-struct-metodlar.md: -------------------------------------------------------------------------------- 1 | # Anonim Struct'lar 2 | 3 | Golang’ta tıpkı anonim fonksiyonlar olduğu gibi anonim struct methodlar da oluşturabiliriz. Örneğimizi görelim: 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func main() { 9 | kişi := struct { 10 | ad, soyad string 11 | }{"Kemal", "Atatürk"} 12 | fmt.Println(kişi) 13 | } 14 | ``` 15 | 16 | Yukarıda struct’ı bir değişken içerisinde tanımladık. Bunu normal struct method olarak yazmaya kalksaydık aşağıdaki gibi yazardık. 17 | 18 | ```go 19 | package main 20 | import "fmt" 21 | type insan struct { 22 | ad, soyad string 23 | } 24 | func main() { 25 | kişi := insan{"Kemal", "Atatürk"} 26 | fmt.Println(kişi) 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /boeluem-3/dilimler-slices.md: -------------------------------------------------------------------------------- 1 | # Dilimler (Slices) 2 | 3 | Dilimler bir dizideki değerlerin istediğimiz bölümünü kullanmamıza yarar. Yani diziyi bir pasta olarak düşünürsek kestiğimiz dilimi yiyoruz sadece. Örneğimize geçelim. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func main() { 9 |  a := [6]int{2, 3, 5, 6, 7, 9} 10 |  fmt.Println(a) //Çıktımız: [2 3 5 6 7 9] 11 |  var b []int = a[2:4] //Dilimleme işlemi 12 |  fmt.Println(b) //Çıktımız: [5 6] 13 | } 14 | ``` 15 | 16 | İnceleme kısmına geçelim. `a` isminde 6 tane `int` tipinde değer alan bir dizi oluşturduk. Çıktımızın içeriğini görmek için ekrana bastırdık. Dilimleme işlemi olarak yorum yaptığım satırda ise `a` dizisinde `2` ve `4` indeksi arasındaki değerleri dizi olarak b’ye kaydettik. b dizisinin içeriğini ekrana bastırdığımızda ise dilimlenmiş alanımızı gördük. Dilimleme işleminde `[ ]` içerisine dilimlemenin başlayacağı ve biteceği indeksi yazarız. 17 | 18 | **Dilim Varsayılanları (Sıfır Değerleri)** 19 | 20 | ```go 21 | package main 22 | import "fmt" 23 | func main() { 24 |  a := [6]int{2, 3, 5, 6, 7, 9} 25 |  var b []int = a[:4] //Boş bırakılan indeks 0 varsayıldı 26 |  fmt.Println(b) //Çıktımız: [2 3 5 6] 27 |  var c []int = a[3:] //Boş bırakıldığı için 3. index ve sonrası alındı 28 |  fmt.Println(c) //Çıktımız: [6 7 9] 29 | } 30 | ``` 31 | 32 | **Dilim Uzunluğu ve Kapasitesi**\ 33 | Bir dilimin **uzunluk** ve **kapasite** değeri vardır. Dilimin uzunluğunu **len()** fonksiyonu ile, kapasitesini ise **cap()** fonksiyonu ile hesaplarız. Örneğimize geçelim. 34 | 35 | ```go 36 | package main 37 | import "fmt" 38 | func main() { 39 |  a := [6]int{2, 3, 5, 6, 7, 9} 40 |  b := a[2:4] 41 |  fmt.Println("a uzunluk", len(a)) 42 |  fmt.Println("a kapasite", cap(a)) 43 |  fmt.Println("a'nın içeriği", a) 44 |  fmt.Println("b uzunluk", len(b)) 45 |  fmt.Println("b kapasite", cap(b)) 46 |  fmt.Println("b'nin içeriği", b) 47 | } 48 | ``` 49 | 50 | b dizisi ile a dizisini dilimlediğimiz için b dizisinin kapasitesi ve uzunluğu değişti. Uzunluk dizinin içindeki değerlerin sayısıdır. Kapasite ise dizinin maksimum alabileceği değer sayısıdır. Çıktımıza bakacak olursak; 51 | 52 | > a uzunluk 6 53 | > 54 | > a kapasite 6 55 | > 56 | > a'nın içeriği \[2 3 5 6 7 9] 57 | > 58 | > b uzunluk 2 59 | > 60 | > b kapasite 4 61 | > 62 | > b'nin içeriği \[5 6] 63 | 64 | **Boş Dilimler (Nil Slices)**\ 65 | Boş bir dilimin varsayılan (sıfır) değeri **nil**’dir. Örnek olarak; 66 | 67 | ```go 68 | package main 69 | import "fmt" 70 | func main() { 71 |  var a []int 72 |  if a == nil { 73 |   fmt.Println("Boş") 74 |  } 75 | } 76 | ``` 77 | 78 | Çıktısı tahmin edeceğiniz üzere **Boş** yazısı olaraktır. 79 | 80 | \ 81 | **Make ile Dilim Oluşturma**\ 82 | Dilimler **make** fonksiyonu ile de oluşturulabilir. Dinamik büyüklükte diziler oluşturabiliriz. 83 | 84 | ```go 85 | a := make([]int, 5) 86 | ``` 87 | 88 | Burada make fonksiyonu ile uzunluğu 5 olan a adında bir dizi oluşturduk. 89 | 90 | ```go 91 | a := make([]int, 0, 5) 92 | ``` 93 | 94 | Burada ise make fonksiyonu ile uzunluğu 0, kapasitesi ise 5 olan a adında bir dizi oluşturduk. 95 | 96 | \ 97 | **Dilime Ekleme Yapma**\ 98 | Bir dilime ekleme yapmak için append fonksiyonu kullanılır. Hemen bir örnek ile kullanılışını görelim. 99 | 100 | ```go 101 | package main 102 | import "fmt" 103 | func main() { 104 |  var a []string 105 |  fmt.Println(a) //[ ] 106 |  a = append(a, "Ali") 107 |  a = append(a, "Veli") 108 |  fmt.Println(a) //[Ali Veli] 109 | } 110 | ``` 111 | 112 | a isminde string tipinde boş bir dizi oluşturduk. Hemen ardından boş olduğunu teyit etmek için a dizisini ekrana bastırdık. Daha sonra a dizisine append fonksiyonu ile “Ali” değerini ekledik. Yine aynı yöntem ile “Veli” değerini de ekledik. Son olarak a dizisinin çıktısının ekrana bastırdığımızda değerlerin eklenmiş olduğunu gördük. 113 | 114 | ```go 115 | fmt.Println(len(a), cap(a)) 116 | ``` 117 | 118 | a dizisinin uzunluk ve kapasitesine baktığımızda aşağıdaki çıktıyı alırız. 119 | 120 | > 2 2 121 | -------------------------------------------------------------------------------- /boeluem-3/diziler-arrays.md: -------------------------------------------------------------------------------- 1 | # Diziler (Arrays) 2 | 3 | Diziler içlerinde bir veya birden fazla değer tutabilen birimlerdir. Bir dizideki her değer sırasıyla numaralandırılır. Numaralandırma sıfırdan başlar. Aynı şekilde örneğe geçelim. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func main() { 9 |  var a [3]string 10 |  a[0] = "Ayşe" //Birinci değer 11 |  a[1] = "Fatma" //İkinci değer 12 |  a[2] = "Hayriye" //Üçüncü değer 13 |  fmt.Println(a) //Çıktımız: [Ayşe Fatma Hayriye] 14 |  fmt.Println(a[1])//Çıktımız: Fatma 15 | } 16 | ``` 17 | 18 | Gelelim kodlarımızın açıklamasına. **a** isminde içerisinde 3 tane **string** tipinde değer barındırabilen bir dizi oluşturduk. a dizisinin birinci değerine yani **0** indeksine **“Ayşe”** atadık. 1 ve 2 indeksine ise “Fatma” ve “Hayriye” değerlerini atadık. a dizisini ekrana bastırdığımızda köşeli parantezler içinde dizinin içeriğini gördük. a’nın 1 indeksindeki değeri bastırdığımızda ise sadece 1 indeksindeki değeri gördük. Dizinin değerlerini tek tek olarak atayabileceğimiz gibi diziyi tanımlarken de değişkenlerini atayabiliriz. 19 | 20 | ```go 21 | package main 22 | import "fmt" 23 | func main() { 24 |  a := [3]string{"Ayşe", "Fatma", "Hayriye"} 25 |  fmt.Println(a) //Çıktımız: [Ayşe Fatma Hayriye] 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /boeluem-3/generics.md: -------------------------------------------------------------------------------- 1 | # Generics 2 | 3 | Bu sayfada Go geliştiricilerin _"Go'da niye generics yok...Go'ya generics nezaman eklenecek?"_ diye diye Go dilinin yaratıcılarına adeta hayatı zindan ettiği Generic'leri inceleyeceğiz. Generics Go'nun 1.18 versiyonu ile dile dahil edildi. 4 | 5 | Generics olmadan da uzun süre boyunca Go yazmak mümkündü tabi ki. Peki bu kadar istenilen bu yapının bize ne gibi faydaları bulunuyor bir bakalım. 6 | 7 | Ufak bir örnek ile başlayalım. 8 | 9 | ```go 10 | package main 11 | 12 | import "fmt" 13 | 14 | func main() { 15 | var sayı1 int = 5 16 | fmt.Println(arttır(sayı1)) 17 | } 18 | 19 | func arttır(sayı int) int { 20 | return sayı + 1 21 | } 22 | ``` 23 | 24 | Yukarıdaki kodlarda basit bir ekleme işlemi yapan bir fonksiyon var. Bu fonksiyonumuz `int` değer alıyor ve `int` değer döndürüyor. 25 | 26 | Bu fonksiyonumuza `int` tipinde `sayı1` değişkenimizi verdik ve ekrana bastırdık. Neyse zaten kod basit kendini açıklıyor ama nedense ben hep bu dökümanın başından beri herşeyi açıklıyorum. Bazı arkadaşlarımız bu yüzden bana kızıyor olabilir :relaxed: 27 | 28 | Eğer `sayı1` değişkenimiz `int` değil de `float64` tipinde olsaydı, arttır fonksiyonumuzu değiştirmemiz gerekirdi. Eğer birden fazla sayı tipi ile işlem yapacağımız durumlar olsaydı, her biri için farklı fonksiyonlar eklememiz gerekecekti. 29 | 30 | Generic'ler ile nasıl yapabileceğimizi görelim. 31 | 32 | ```go 33 | package main 34 | 35 | import "fmt" 36 | 37 | func main() { 38 | var sayı1 int = 5 39 | var sayı2 float64 = 5.3 40 | fmt.Println(arttır(sayı1)) 41 | fmt.Println(arttır(sayı2)) 42 | } 43 | 44 | func arttır[n int | float64](sayı n) n { 45 | return sayı + 1 46 | } 47 | ``` 48 | 49 | `main` bloğunun içinde baktığımızda farklı değişken tipindeki 2 sayıyı aynıyı fonksiyona parametre olarak verdik. 50 | 51 | Bunu nasıl yaptığımız büyük bir sır değil tabiki. Biraz daha aşağıya baktığımızda kendini belli ediyor. `arttır` fonksiyonunun parametre parantezlerinden önce köşeli parantez açarak, bu kısma `n` isminde `int` veya `float64` tipinde değer alabilen bir tip oluşturduk. Fonksiyonumuzun parametre parantezinde `n` tipi ile belirlediğimiz tipte değerler alabilir hale geldik. 52 | 53 | Yukarıdaki örneğimizde oluşturduğumuz generic fonksiyonda parametre tiplerinde kısıtlama yaptık. 54 | -------------------------------------------------------------------------------- /boeluem-3/map.md: -------------------------------------------------------------------------------- 1 | # Map 2 | 3 | **Map**’in Türkçe karşılığında yapacağı işlemi anlatan bir çeviri olmadığı için anlamı yerine yaptığı işi bilelim. Map ile bir değişken içerisindeki dizileri bölge olarak ayırabiliriz. Çok karmaşık bir cümle oldu. O yüzden örneğimize geçelim ki anlaşılır olsun. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | type insan struct { 9 |  kisi1, kisi2, kisi3 string 10 | } 11 | func main() { 12 |  var m map[string]insan 13 |  m = make(map[string]insan) 14 |  m["isim"] = insan{ 15 |   "Ali", "Veli", "Ahmet", 16 |  } 17 |  fmt.Println(m["isim"]) 18 | } 19 | ``` 20 | 21 | Yukarıda **insan** isminde bir **struct** metodu oluşturduk ve içerisine **string** tipinde 3 tane değişken girdik. **main()** fonksiyonumuz içerisinde ise **m** adında **map** kullanarak **string** değer saklayabilen **insan** tipinde değişken oluşturduk. **m** değişkenini **make** ile **map dizisi** haline getirdik. Hemen aşağısında ise **m** değişkenine **“isim”** adında bir bölge oluşturduk ve **insan** **struct**’ında belirttiğimiz gibi 3 tane **string** değer girdik. Son olarak **m** dizisinin isim bölgesindeki değerleri ekrana bastırmasını istedik. Çıktımız şöyle olacaktır; 22 | 23 | > {Ali Veli Ahmet} 24 | 25 | **Birden Fazla Bölge Ekleme**\ 26 | Önceki yazımızda map ile dizilere bölgesel hale getirmeyi gördük. Şimdi de birden fazla bölgeyi nasıl yapacağımızı göreceğiz. Örneğimize geçelim. 27 | 28 | ```go 29 | package main 30 | import "fmt" 31 | type insan struct { 32 |  kisi1, kisi2, kisi3 string 33 | } 34 | var m = map[string]insan{ 35 |  "erkekler": insan{"Ali", "Veli", "Ahmet"}, 36 |  "kadinlar": insan{"Ayşe", "Fatma", "Hayriye"}, 37 | } 38 | func main() { 39 |  fmt.Println(m["erkekler"]) 40 |  fmt.Println(m["kadinlar"]) 41 |  fmt.Println(m) 42 | } 43 | ``` 44 | 45 | Yukarıda önceki örneğimizdeki gibi **insan struct**’ı oluşturduk ve içine **3** tane **string** tipinde değer atadık. **m** adında dizi oluşturduk ve **map** ile bölgeli bir dizi olduğunu belirttik. Dizinin içerisine **“erkekler”** isminde **insan** tipinde bir bölge oluşturduk ve içine **3** tane **string** tipinde değerimizi girdik. Aynı işlemi **“kadinlar”** isimli bölge içinde yaptık. **main** fonksiyonumuz içerisinde **erkekler** ve **kadinlar** bölgemizi ekrana bastırdık. Son olarak **m** dizisindeki tüm içeriği ekrana bastırık.\ 46 | Çıktımız ise şöyle olacaktır; 47 | 48 | > {Ali Veli Ahmet}\ 49 | > {Ayşe Fatma Hayriye}\ 50 | > map\[erkekler:{Ali Veli Ahmet} kadinlar:{Ayşe Fatma Hayriye}] 51 | 52 | Burada ayrıntıyı farkedelim. **m** dizisini ekrana bastırdığımızda map yeni bölgeli bir dizi olduğunu vurguluyor. Map ile bir bakıma dizi içerisine yeni bir dizi ekliyorsunuz. Tabi bunu **struct metodu** ile yapıyoruz. 53 | 54 | \ 55 | **Bölgesel Silme İşlemi**\ 56 | **delete** fonksiyonu ile silme işlemimizi yapabiliriz. Hemen örneğimize geçelim. 57 | 58 | ```go 59 | package main 60 | import "fmt" 61 | func main() { 62 |  m := make(map[string]int) //m isminde string bölge isimli int değer taşıyan dizi 63 |  m["sayi"] = 25 //sayi bölgesine 25 değerini yerleştirdik 64 |  fmt.Println(m["sayi"]) //Çıktımız: 25 65 |  delete(m, "sayi") //sayi bölgesindeki değeri sildik 66 |  fmt.Println(m["sayi"]) //Çıktımız: 0 (sıfır) 67 | } 68 | ``` 69 | -------------------------------------------------------------------------------- /boeluem-3/range.md: -------------------------------------------------------------------------------- 1 | # Range 2 | 3 | **Range**, üzerinde kullanıldığı diziyi **for** döngüsü ile tekrarlayabilir. Bir dilim range edildiğinde, tekrarlama başına iki değer döndürür (return). Birinci değer dizinin **indeksi**, ikinci değer ise bu indeksin içindeki **değerdir**. Örneğimize geçelim. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | var isimler = []string{"Ali", "Veli", "Hasan", "Ahmet", "Mehmet"} 9 | func main() { 10 |  for a, b := range isimler { 11 |   fmt.Printf("%d. indeks = %s\n", a, b) 12 |  } 13 | } 14 | ``` 15 | 16 | Yukarıdaki yazdığımız kodları açıklayalım. **isimler** isminde içerisinde **string** tipinde değerler olan bir **dizi** oluşturduk.\ 17 | For döngümüz ile dizinimizdeki değerleri sıralayacak bir sistem oluşturduk. Döngümüzü açıklayacak olursak, bahsettiğimiz gibi dizi üzerinde uygulanan **range** terimi iki değer döndürecek olduğundan bu değerleri kullanabilmek için **a** ve **b** adında argüman belirledik. **range** **isimler** diyerek **isimler** dizisini kullanacağımızı belirttik. Ekrana bastırma bölümümüzde ise **%** işaretleri ile sağ taraftan hangi değerleri nerede kullanacağımızı belirttik.\ 18 | Çıktımız ise şu şekilde olacaktır. 19 | 20 | > 0. indeks = Ali 21 | > 1. indeks = Veli 22 | > 2. indeks = Hasan 23 | > 3. indeks = Ahmet 24 | > 4. indeks = Mehmet 25 | -------------------------------------------------------------------------------- /boeluem-3/struct-fonksiyonlar-methodlar.md: -------------------------------------------------------------------------------- 1 | # Struct Fonksiyonlar (Methodlar) 2 | 3 | Bu bölümde bir struct'a özel nasıl fonksiyon oluşturacağımızı göreceğiz. 4 | 5 | Örneğimizi görelim: 6 | 7 | ```go 8 | package main 9 | 10 | import "fmt" 11 | 12 | type insan struct { 13 | isim string 14 | yaş int 15 | } 16 | 17 | func (i insan) tanıt() { 18 | fmt.Printf("Merhaba, Ben %s. %d yaşındayım.", i.isim, i.yaş) 19 | } 20 | func main() { 21 | kişi := insan{"Kaan", 23} 22 | kişi.tanıt() 23 | } 24 | ``` 25 | 26 | `insan` isminde bir struct tipi oluşturduk. Bu yapımızın tıpkı insanlarda olduğu gibi `isim` ve `yaş` değişkenleri var. 27 | 28 | Hemen aşağısında bir fonksiyon oluşturduk. Bu fonksiyonumuzun özelliği ise fonksiyonun isminden önce parantez içerisinde hangi struct'ta çalışacağını belirtmemizdir. `insan` struct'ının içerindeki değişkenlere ise `i` değişkeni ile eriştik. 29 | 30 | Daha sonra `main` fonksiyonumuzda `kişi` isminde `insan` tipinde bir nesne oluşturduk. `kişi.tanıt()` yazarak `insan` struct tipinde oluşturduğumuz nesne için olan `tanıt` fonksiyonumuzu çalıştırdık. 31 | 32 | Çıktımızı görelim: 33 | 34 | > Merhaba, Ben Kaan. 23 yaşındayım. 35 | 36 | Tabii burada, `fmt.Prtinf` fonksiyonu içerisinde kullanılan `%s` ve `%d` ifadelerinini anlamamış olabilirsiniz. Bu ifadeler, fonksiyonun ilk argümanından sonra verilen değişkenlerin karakter dizisi (string) içerisinde kullanılabilmesine olanak sağlar. Veri tipi olarak `%s` kullanıldığı durumlarda string türü verileri, `%d` kullanıldığı durumlarda ise integer türü verilerin yerleştirileceğini belirtir. Doğru veri tipi için ifade seçilmediği durumlarda program hata vermeyecek ancak doğru çalışmayacaktır. 37 | 38 | Bu konuya, ileride `String Formatlama` bölümünde değineceğiz. 39 | -------------------------------------------------------------------------------- /boeluem-3/struct.md: -------------------------------------------------------------------------------- 1 | # Struct 2 | 3 | Go programlama dilinde sınıflar yoktur. Sınıflar yerine struct'lar (yapılar) vardır. Yapılar sayesinde bir nesne oluşturabilir ve bu nesneye ait özellikler oluşturabiliriz. Örnek bir struct oluşturalım. 4 | 5 | {% code title="struct örneği" %} 6 | ```go 7 | type kişi struct { 8 | isim string 9 | soyİsim string 10 | yaş int 11 | } 12 | ``` 13 | {% endcode %} 14 | 15 | `type` terimi ile yeni bir tür oluşturabiliyoruz. İsmini `kişi` olarak verdik ve türünün de `struct` olacağını söyledik. Yukarıdaki şekilde bir yapı oluşturmuş olduk. Bu yapı içerisinde `isim`, `soyİsim` ve `yaş` değişkenlerine sahip. Yukarıdaki yapı üzerinden bir nesne örneği oluşturduğumuzda örneğimiz bu değişkenlere sahip olacak. 16 | 17 | {% code title="Örnek Kullanım:" %} 18 | ```go 19 | package main 20 | 21 | import "fmt" 22 | 23 | type kişi struct { 24 | isim string 25 | soyİsim string 26 | yaş int 27 | } 28 | 29 | func main() { 30 | 31 | kişi1 := kişi{"Kaan", "Kuşcu", 23} 32 | 33 | fmt.Println(kişi1) 34 | 35 | } 36 | ``` 37 | {% endcode %} 38 | 39 | `main()` fonksiyonunun içerisini incelediğimizde, `kişi1` isminde `kişi{}` yapısında bir nesne örneği oluşturuyoruz. İçerisine oluşturucu parametreler olarak `kişi struct`'ındaki sıralamayı göz önünde bulundurarak parametrelerimi giriyoruz. Daha sonra kişi1 nesne örneğini ekrana bastırıyoruz. Çıktımız aşağıdaki gibi olacaktır: 40 | 41 | > {Kaan Kuşcu 23} 42 | 43 | Yukarıdaki örnekte nesneyi tanımlama sırasında değer atamasını yaptık. Nesnenin alt değişkenlerine ulaşarak da tanımlama yapabilirdik. 44 | 45 | ```go 46 | kişi1 := kişi{"Kaan", "Kuşcu", 23} 47 | kişi1.isim = "Ahmet" 48 | kişi1.soyİsim = "Karaca" 49 | kişi1.yaş = 34 50 | 51 | fmt.Println(kişi1) //{Ahmet Karaca 34} 52 | ``` 53 | 54 | Nesne örneğini oluşturuyorken parametreleri boş bırakıp sonradan da atama yapabilirdik. 55 | 56 | ```go 57 | kişi1 := kişi{} 58 | kişi1.isim, kişi1.soyİsim = "M. K.", "ATATÜRK" 59 | kişi1.yaş = 999 60 | 61 | fmt.Println(kişi1) //{M. K. ATATÜRK 999} 62 | ``` 63 | 64 | ## İsim Belirterek Tanımlama 65 | 66 | Nesneye özel değişkenleri tanımlarken değişken ismini belirterek de tanımlama yapabiliriz. 67 | 68 | ```go 69 | kişi1 := kişi{soyİsim: "Kuşcu", isim: "Kaan", yaş: 23} 70 | 71 | fmt.Println(kişi1) //{Kaan Kuşcu 23} 72 | ``` 73 | 74 | Değişken ismini belirterek atama yaptığımız için sıralamaya dikkat etmemiz gerekli değildir. 75 | -------------------------------------------------------------------------------- /boeluem-4/anonim-goroutine-fonksiyonlar.md: -------------------------------------------------------------------------------- 1 | # Anonim Goroutine Fonksiyonlar 2 | 3 | Bu yazımız **Goroutine** ve **Kanallar** dersi için biraz alıştırma tadında olacak.\ 4 | \ 5 | Daha önceki yazılarımızda belirli bir fonksiyonu **Goroutine** ile **asenkron** (eş zamanlı) olarak çalıştırmayı gördük. Bu yazımızda da **anonim** bir Goroutine fonksiyonunu göreceğiz. Bu fonksiyonun özelliği bir ismi olmaması ve asenkron olarak çalışmasıdır. Örneğimizi görelim. 6 | 7 | ```go 8 | package main 9 | import ( 10 | "fmt" 11 | "time" 12 | ) 13 | func main() { 14 | go func() { 15 | time.Sleep(time.Second * 2) 16 | fmt.Println("İlk yazımız") 17 | }() 18 | fmt.Println("İkinci yazımız") 19 | } 20 | ``` 21 | 22 | Açıklamasına gelirsek **go func()** ile anonim bir fonksiyon oluşturduk. Bu tür fonksiyonda fonksiyonumuzun sonuna **( )** parantezlerimizi yerleştirmek zorundayız. Çünkü fonksiyonumuza parametreleri bu parantezler içerisinde yolluyoruz. Şuanlık parametre yollamadığımzın için boş kalacak. Bu fonksiyonumuz programın geri kalanı ile aynı zamanda çalışacak. Hatta programın geri kalanı ile bağlantısı bile olmayacak. Bu sebepten ötürü mantıken 2 saniye sonra işlem yapmasını belirttiğimiz için **“İkinci yazımız”** metni gözüktükten sonra **“İlk yazımız”** metni gözükeceğini tahmin etsekte **go func()** fonksiyonu yapısı gereği zaman bağımsız çalışacağı için **fmt.Println(“İkinci yazımız”)** fonksiyonu tamamlandıktan sonra **“İlk yazımız”** metni ekrana bastırılmayacaktır bile. İsterseniz programı çalıştırıp deneyebilirsiniz.\ 23 | Bunun önüne geçebilmein yolu **go func()** fonksiyonundaki işlemlerin programın çalışma zamanı içerisinde sonuç vermesidir. 24 | 25 | ```go 26 | package main 27 | import ( 28 | "fmt" 29 | "time" 30 | ) 31 | func main() { 32 | go func() { 33 | time.Sleep(time.Second * 2) 34 | fmt.Println("İlk yazımız") 35 | }() 36 | fmt.Println("İkinci yazımız") 37 | time.Sleep(time.Second * 3) 38 | } 39 | ``` 40 | 41 | Yukarıdaki mantıkla çalışması için zamanı böyle ayarlamamız gerekir. Ama bu yöntem çok boş (gereksiz) bir yöntemdir. Her zaman böyle zamanı tahmin edemeyiz. Örnek olarak, **go func()** fonksiyonunda internet üzerinden bir dosyanın inmesini bekleyecek olsaydık tahmini bir zaman belirleyemezdik. Ki koskoca Windows bile belirleyemiyor. Çünkü bu internet hızımız ile alaklı bir şeydir. Bu yüzden garanti bir yöntem değildir. 42 | 43 | \ 44 | Bundan %100 daha garantili olan yöntem **kanallar** üzerinden haberleşmektir. Çünkü bir yerde kanal ataması yapıldığında program akışının devam edebilmesi için mutlaka kanaldan gelecek verinin beklenmesi gerekir. Bu sayede zaman ile alakalı işlerde tahmin yürütmemize gerek kalmaz. Biraz uzun bir açıklama oldu ama örneğimizi görünce mantığını anlayacaksınız. 45 | 46 | ```go 47 | package main 48 | import ( 49 | "fmt" 50 | "time" 51 | ) 52 | func main() { 53 | kanal := make(chan string) //kanal oluşturuyoruz 54 | go func() { 55 | time.Sleep(time.Second * 2) //2 saniye uyku 56 | kanal <- "Kanal bitti" //İletişime geçiriyoruz 57 | fmt.Println("Anonim fonksiyon yazısı") 58 | }() 59 | fmt.Println("Öylesine bir yazı") 60 | fmt.Println(<-kanal) //kanaldan gelen veri bekleniyor 61 | } 62 | ``` 63 | 64 | Öncelikle kanal ile ilgili işlemler yapabilmek için **make** fonksiyonu ile kanal oluşturduk. Hemen altında kanalımızı iletişime sokmak için öylesine bir **string** değer yolladım. 65 | 66 | \ 67 | **go func()** fonksiyonumuz yukarıdaki örnekler ile aynıdır. Bu fonksiyonumuzun 2 saniye beklemesi olduğundan dolayı fonksiyonumuzun altındaki **“Öylesine bir yazı”** daha önce görüntülenecek. Buraya kadar ilk örnek ile aynı olayla sonuçlanıyor. Programın sonlanmasını engellemek için **<- kanal** içinden değeri bastırarak kanal iletişimini beklemesini ve bundan dolayı **“Anonim fonksiyonu yazısı”**‘nı da beklemiş oluyoruz.\ 68 | \ 69 | Anonim Goroutine fonksiyonları bu şekilde kullanabiliriz. 70 | -------------------------------------------------------------------------------- /boeluem-4/kanallar-channels.md: -------------------------------------------------------------------------------- 1 | # Kanallar (Channels) 2 | 3 | **Kanallar**, Go dilinde asenkron programlama yaparken değer aktarımı yapabileceğimiz hatlardır. Kanala değer atanması iş parçacığı tarafından bekleneceği için asenkron işlemler arasındaki senkronizasyonu ayarlayabiliriz. Kanallar `make()` fonksiyonu ile oluşturulur. 4 | 5 | {% code title="Örnek" %} 6 | ```go 7 | k := make(chan bool) 8 | ``` 9 | {% endcode %} 10 | 11 | Yukarıdaki örnekte `make()` fonksiyonu ile `k` isminde bir kanal oluşturduk. Bu kanalın özelliği `bool` tipinde değer taşımasıdır. Yani bu kanal ile `true` veya `false` değerlerini taşıyabiliriz. Kanala değer göndermek için `<-` işaretini kullanırız. Yani bir nevi atama işlemi yapıyoruz. Atama işleminden farkı, kanala atama işlemi yapılana kadar iş parçacığının devam etmemesidir. 12 | 13 | {% code title="Örnek Atama" %} 14 | ```go 15 | k <- true 16 | ``` 17 | {% endcode %} 18 | 19 | Atama işlemi ile kanalımıza değer yolladık. Bir de bu kanalın çıkış noktası olması gerekir. Bu çıkış noktasında, ister kanaldan gelen veriyi bir değişkene atayabiliriz, istersek de sadece kanala veri gelmesini bekleyebiliriz. 20 | 21 | {% code title="Kanaldan gelen değeri değişkene atama" %} 22 | ```go 23 | a := <-k 24 | ``` 25 | {% endcode %} 26 | 27 | Yukarıdaki örnekte `a` isimli değişkene `k` kanalından gelen `bool` tipinde değer atadık. `a` değişkenine atama işlemi `k` kanalına değer gönderildiği zaman yapılacaktır. Yani `k` kanalına değer gelene kadar iş parçacığı duraklatılacaktır. _(Program `k` kanalına gelecek değeri bekler.)_ 28 | 29 | {% code title="Sadece kanala değer gelmesini beklemek" %} 30 | ```go 31 | <- k 32 | ``` 33 | {% endcode %} 34 | 35 | Yukarıdaki anlatılanlardan yola çıkarak bir örnek oluşturalım. 36 | 37 | {% code title="Örnek kanal işlemleri" %} 38 | ```go 39 | package main 40 | 41 | import ( 42 | "time" 43 | ) 44 | 45 | func main() { 46 | 47 | //bir kanal oluşturalım 48 | k := make(chan bool) 49 | //bu kanalımız bool değer taşıyacak 50 | 51 | //asenkron bir iş parçacığı oluşturalım 52 | go func() { 53 | 54 | //bu iş parçacığı 5 sn beklesin 55 | time.Sleep(time.Second * 5) 56 | 57 | //k kanalına bool bir değer gönderelim 58 | k <- true 59 | }() 60 | 61 | //ana iş parçacığı k kanalına değer gelene kadar bekleyecek 62 | <-k 63 | //değer geldiğinde program sonlanacaktır. 64 | } 65 | ``` 66 | {% endcode %} 67 | 68 | ## Boyutlu Kanal Oluşturma 69 | 70 | Oluşturduğumuz kanala boyut vermek de mümkün. Yani kanalımıza birden fazla değer yollayabiliyoruz. Bunun için kanalı oluştururken `make()` fonksiyonunda boyutu da belirtelim. 71 | 72 | {% code title="Örnek" %} 73 | ```go 74 | package main 75 | 76 | import ( 77 | "fmt" 78 | "time" 79 | ) 80 | 81 | func main() { 82 | 83 | //2 adet bool değer taşıyan bir kanal oluşturalım 84 | k := make(chan bool, 2) 85 | 86 | 87 | //asenkron bir iş parçacığı oluşturalım 88 | go func() { 89 | 90 | //5 sn beklesin 91 | time.Sleep(time.Second * 5) 92 | 93 | //k kanalına bool bir değer gönderelim 94 | k <- true 95 | 96 | //tekrardan 2 sn beklesin 97 | time.Sleep(time.Second * 2) 98 | 99 | //ve k kanalına 2. değer de gönderilsin. 100 | k <- false 101 | }() 102 | 103 | //ana iş parçacığı k kanalına 2 değer gelene kadar bekleyecek 104 | fmt.Println(<-k, <-k) //çıktı: true false 105 | //iki bool değeri de baştırmak için k kanalını 2 defa yazdık 106 | } 107 | ``` 108 | {% endcode %} 109 | 110 | Ana iş parçacığı _(`main()` içerisine yazılan kodlar)_ devam etmek için `k` kanalına gelen 2 değeri de bekleyecektir. 111 | 112 | `fmt.Println()` içerisine sadece bir defa `<-k` yazsaydık, `k` kanalına ilk gelen değeri ekrana bastıracaktı. 113 | -------------------------------------------------------------------------------- /boeluem-4/mutex-ile-asenkron-islem-sirasi.md: -------------------------------------------------------------------------------- 1 | # Mutex ile Asenkron İşlem Sırası 2 | 3 | Size konu başlığını şöyle açıklayayım. Örneğin bir banka uygulaması para çekme ve yatırma gibi özelliklere sahiptir. Programlama mantığında para yatırmak ve çekmek için mevcut para miktarını bilmemiz gerekir. Banka uygulamasının mantığı en basit derecede bu şekilde çalışır. 4 | 5 | Banka hesabımızda asenkron işlem yapıldığını varsayalım. Yani bir hesaptan aynı anda birden fazla kullanıcı işlem yapıyor olsun. 6 | 7 | Örneğin hesabımızda 100₺ olsun. Birinci kullanıcı 20₺ yatırsın. Aynı anda ikinci kullanıcı 50₺ çeksin. Bu iki kullanıcınında kullandığı program işlem yapmaya başladığında önce para miktarını alıyor. Daha sonra yapılacak işleme göre ya ekleme ya da çıkarma işlemi yapıyor. Fakat birden fazla kullanıcı aynı anda bu işlemi yaparsa hesaptaki parada yanlışlık olacaktır. 8 | 9 | Basit bir görsel ile inceleyelim. 10 | 11 | İşlemlere aynı anda başlandığını varsayalım. 12 | 13 | ![Örnek asenkron işlem](../.gitbook/assets/mutex.png) 14 | 15 | Bu işlemin sonuncunda hangi kullancının işlemi sonuncu olarak biterse para miktarı onun sonucu olur. Yani kullanıcı 2'nin işlemi kullanıcı 1'den sonra biterse yeni para miktarı 50₺ olur. 16 | 17 | Bu gibi örneklerde asenkron işlemlere sıra verilmesi gerekir. Mutex tam olarak bu işi yapıyor. Bunun için bir Mutex nesnesi oluşturuyoruz. İşlemlerimizi bu nesne üzerinden yapıyoruz. Bu nesne aynı anda sadece bir işlemi gerçekleştiriyor. Bu yüzden sıra işlemi sağlıyor. Önce başlayan asenkron işlem ilk sırada oluyor. Tamamlanınca diğerine sıra geçiyor. Böyle düşündüğümüz zaman "bunun senkron programlamadan ne farkı var?" diyebilirsiniz. Farkı asenkron fonksiyonların içindeki istediğimiz kısımları senkron çalıştırmamız. 18 | 19 | Örnek bir para yatırma-çekme uygulaması yazalım. İşlemin sağlık çalışması için, para miktarıyla aynı anda sadece bir kişi işlem yapabilmelidir. 20 | 21 | ```go 22 | package main 23 | 24 | import ( 25 | "fmt" 26 | "sync" // mutex'i kullanmak için 27 | ) 28 | //global olarak mutex nesnesi oluşturalım. 29 | var mt sync.Mutex 30 | 31 | 32 | func paraÇek(bakiye *float64, çekilecekMiktar float64, wg *sync.WaitGroup) { 33 | /* 34 | * mt isimli mutex'i bu işlem yapılırken kilitliyoruz. 35 | * bu sayede mt mutex'ini başka işlemler kullanamıyor. 36 | */ 37 | mt.Lock() 38 | 39 | /* 40 | bu kısımda asenkron olmasını istemediğimiz işlemi yapalım. 41 | */ 42 | *bakiye -= 15 43 | fmt.Printf("Yeni Bakiye: %.2f\n", *bakiye) 44 | 45 | /* 46 | * diğer işlemlerinde kullanabilmesi için mutex'i tekrardan açalım. 47 | * mt mutex açılınca diğer asenkron işlemdeki mt mutex'i çalışmaya başlar. 48 | */ 49 | mt.Unlock() 50 | fmt.Println("Çekme işlemi tamamlandı.") 51 | 52 | /* 53 | * waitgroup ile işlemin tamamlandığını belirttik. 54 | * böylece wg havuzu 2'den 1'e düştü 55 | */ 56 | wg.Done() 57 | } 58 | 59 | //bu fonksiyonda yukarıdaki ile aynı mantıkta 60 | func paraYatır(bakiye *float64, yatırılacakMiktar float64, wg *sync.WaitGroup) { 61 | mt.Lock() 62 | *bakiye += 65 63 | fmt.Printf("Yeni Bakiye: %.2f\n", *bakiye) 64 | mt.Unlock() 65 | fmt.Println("Yatırma işlemi tamamlandı.") 66 | wg.Done() 67 | } 68 | 69 | func main() { 70 | 71 | /* 72 | * asenkron işlemlerimizin, ana iş parçacığında tamamlanmasını 73 | * beklemek için waitgroup nesnesi oluşturalım 74 | */ 75 | var wg sync.WaitGroup 76 | 77 | //2 fonksiyonu da bekleyeceğimiz için Add'e 2 yazalım 78 | wg.Add(2) 79 | 80 | //fonksiyonlarımızın kullancağı bakiye değişkenimiz 81 | var bakiye float64 = 100 82 | fmt.Printf("İlk Bakiye: %.2f\n", bakiye) 83 | 84 | /* 85 | * paraÇek ve paraYatır fonksiyonlarımızı aynı anda başlatıyoruz. 86 | * hangisi daha önce başlarsa mutex sırasına ilk o girer. bu esnada diğer 87 | * fonksiyon mutex'in açılmasını bekler. 88 | */ 89 | go paraÇek(&bakiye, 25, &wg) 90 | go paraYatır(&bakiye, 65, &wg) 91 | 92 | /* 93 | * ana iş parçacığı tamamlandığında asenkron çalışan fonksiyonları beklemez. 94 | * beklemediğinde de asenkron fonksiyonlar çalışmadan program sonlanır. 95 | * ana iş parçacığının asenkron işlemleri beklemesi için waitgroup sonucunun 0 olmasını bekleriz. 96 | * wg.Add(2) yazarak 2 adet wg.Done() fonksiyonu çalıştığında wg.Add(0) olur ve 97 | * wg.Wait() tamamlanır ve program başka işlemler yapılmıyor ise sonlanır. 98 | */ 99 | wg.Wait() 100 | } 101 | ``` 102 | 103 | Çıktımız aşağıdaki gibi olacaktır. 104 | 105 | > İlk Bakiye: 100.00\ 106 | > Yeni Bakiye: 165.00\ 107 | > Yatırma işlemi tamamlandı.\ 108 | > Yeni Bakiye: 150.00\ 109 | > Çekme işlemi tamamlandı. 110 | 111 | Yukarıdaki çıktıya göre, `paraYatır()` fonksiyonu `paraÇek()` fonkisyonundan önce çalışmıştır. 112 | -------------------------------------------------------------------------------- /boeluem-4/select.md: -------------------------------------------------------------------------------- 1 | # Select 2 | 3 | **Select** ile çoklu goroutine işlemlerinin iletişimini bekleyebiliriz. Örneğimizi görelim: 4 | 5 | ```go 6 | package main 7 | import ( 8 | "fmt" 9 | "time" 10 | ) 11 | func main() { 12 | k1 := make(chan string) 13 | k2 := make(chan string) 14 | go func() { 15 | time.Sleep(time.Second * 1) 16 | k1 <- "video" 17 | }() 18 | go func() { 19 | time.Sleep(time.Second * 3) 20 | k2 <- "ses" 21 | }() 22 | for i := 0; i < 2; i++ { 23 | select { 24 | case mesaj1 := <-k1: 25 | fmt.Println("Mesaj 1:", mesaj1) 26 | case mesaj2 := <-k2: 27 | fmt.Println("Mesaj 2:", mesaj2) 28 | } 29 | } 30 | } 31 | ``` 32 | 33 | Yukarıdaki kodların bize **ses** ve **video** verisi sağlayacak bir programdan parça olduğu senaryosunu kuralım. Bu programda işlem yapabilmemiz için bize bu 2 verinin gelmesini beklememiz lazım. Verileri bekleme işlemini **select** ile yapıyoruz. Burada dikkat etmemiz gereken nokta **2** tane veri beklediğimiz için **for** atamalarında **i < 2** olarak girmeliyiz. Çünkü **i := 0** olduğu için **i 2** olana kadar arada **2** sayı var. Bu sayı boşluğu da 2 veri almayı beklememizi sağlıyor. Örnek olarak **i < 1** girip 2 veri almaya kalksak **k2**‘den gelen veriyi beklemeyecek bile. Tam tersi olarak 2 veri alacağımız halde **i < 4** girsek program **deadlock**‘a girecektir. Yani başarısız bir program olacaktır. 34 | -------------------------------------------------------------------------------- /boeluem-4/untitled.md: -------------------------------------------------------------------------------- 1 | # Goroutine 2 | 3 | **Goroutine**’ler **Go Runtime** tarafından yönetilen hafif bir sistemdir. Bir işlemi eşzamanlı olarak yapmak istiyorsak, Goroutine'den faydalanabiliriz. Bu sayede aynı çalışma-zamanı içerisinde birden fazla iş parçacığı oluşturabiliriz. 4 | 5 | ## Terimler 6 | 7 | ### Ana iş parçacığı 8 | 9 | `Main()` fonksiyonu içerisine yazdığımız, asenkron olmayan kodlardır. Varsayılan olarak Go Runtime bu iş parçacığını izler. Programımız asenkron işlemlerin tamamlanmasını beklemiyorsa, ana iş parçacığı tamamlandığında program sona erer. 10 | 11 | ### Eşzamanlılık 12 | 13 | Eşzamanlılık, programlamada bir işlem gerçekleşirken, aynı zamanda başka işlemlerin de gerçekleşmesidir. 14 | 15 | ## Eşzamanlı Bir İşlem Oluşturalım 16 | 17 | Eşzamanlı bir işlem oluşturmak için `go` anahtar kelimesinden faydalanabiliriz. Bunun için eşzamanlı çalışacak işlemin başına `go` yazmamız yeterli olacaktır. 18 | 19 | ![Asenkron İşlem Örneği](../.gitbook/assets/2020-11-09\_23-38.png) 20 | 21 | Aslında yukarıdaki örnekte `time.Sleep()` kullanarak 2 saniye bekletmemizin bir sebebi. Eğer `time.Sleep()` eklememiş olsaydık, ekrana _"Merhaba Dünya!"_ yazıldıktan sonra programımız sonlanacaktı. Bunun sebebi Go Runtime'ının Sadece Ana iş parçacığını beklemesi. Ana iş parçacığındaki işlemler sonlandıktan sonra, diğer işlemleri beklemiyor. Yukarıdaki örnekte bunu engellemek için `time.Sleep()` kullandık. Böylece program 2 saniye beklerken eşzamanlı işlemimiz de tamamlandı. Tabii `time.Sleep()` kullanarak beklemek mantıklı bir yöntem değil. İşlemin ne kadar süreceğini bilmediğimiz durumlar olacaktır. Bunun için Kanalları kullanabiliriz. 22 | -------------------------------------------------------------------------------- /boeluem-4/waitgroup-ile-goroutinein-tamamlanmasini-beklemek.md: -------------------------------------------------------------------------------- 1 | # WaitGroup ile Asenkron İşlemleri Beklemek 2 | 3 | Goroutine’leri Asenkron programlama yaparken kullanırız. Böylece aynı anda birden fazla işlem gerçekleştirebiliriz. Peki programımızın belirttiğimiz asenkron işlemleri bekleme gibi bir ihtiyacı olsaydı, ne yapmamız gerekirdi? Bu durumlarda WaitGroup'lardan faydalanabiliriz. Örneğin projemizde 3 adet asenkron işlem bulunuyorsa, WaitGroup'a 3 değerini ekleriz. Her asenkron işlem tamamlandığında WaitGroup -1 azalır ve sıfıra geldiğinde WaitGroup tamamlanmış olur. WaitGroup'u kullanmak için ise "sync" paketini projemize dahil ediyoruz. Kodlar üzerinde açıklamasını görelim. 4 | 5 | {% code title="main.go" %} 6 | ```go 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "sync" //WaitGroup'u kullammak için 12 | "time" //bekleme işlemleri için 13 | ) 14 | 15 | /* 16 | * waitgroup nesnesini işaretçi olarak parametre veriyoruz. 17 | * işaretçi olarak vermemizin sebebi, programın bekleme işlemi için 18 | * asıl waitgroup nesnesini kontrol etmesidir. 19 | */ 20 | func fonksiyon1(wg *sync.WaitGroup) { 21 | 22 | //fonksiyonun 2 sn beklemesini istiyoruz. 23 | time.Sleep(2 * time.Second) 24 | fmt.Println("Fonk1 tamamlandı") 25 | 26 | //wg.Done() fonksiyonu ile waitgroup nesnesini -1 azalttık. 27 | wg.Done() 28 | } 29 | 30 | //bu fonksiyonumuza da wg nesnesini işaretçi ile parametre olarak verdik. 31 | func fonksiyon2(wg *sync.WaitGroup) { 32 | //fonksiyonu 3 sn uyuttuk. 33 | time.Sleep(3 * time.Second) 34 | fmt.Println("Fonk2 tamamlandı") 35 | 36 | //-1 daha eksilttik. 37 | wg.Done() 38 | } 39 | 40 | func main() { 41 | /* 42 | * Öncelikle waitgroup'u kullanabilmek için bir waitgroup 43 | * nesnesi oluşturuyoruz. 44 | */ 45 | var wg sync.WaitGroup 46 | 47 | /* 48 | * waitgroup'a 2 ekliyoruz. Yani 2 tane işlemden yanıt gelmesini 49 | * beklemesini istiyoruz. Aslında burada beklemeyecek. Sadece 50 | * işlem sayısını belirttik. 51 | */ 52 | wg.Add(2) 53 | 54 | /* 55 | * fonksiyon1 ve fonksiyon2'ye oluşturduğumuz wg örneğinin 56 | * bellekteki adresinin veriyoruz. 57 | */ 58 | go fonksiyon1(&wg) 59 | go fonksiyon2(&wg) 60 | fmt.Println("Merhaba Dünya!") 61 | 62 | /* 63 | * Burada wg.Wait() fonksiyonu ile asenkron işlemleri beklemesini 64 | * sağlıyoruz. yani waitgroup'un 0'a düşmesini bekliyoruz. 65 | * Eğer waitgroup olmadan yapsaydık. asenkron fonksiyonlarımızın tamamlanmasını 66 | * beklemeden program kendini sonlandırırdı. 67 | */ 68 | wg.Wait() 69 | 70 | //waitgroup tamamlandığında ekrana yazı bastıralım. 71 | fmt.Println("WaitGroup'lar tamamlandı.") 72 | } 73 | ``` 74 | {% endcode %} 75 | -------------------------------------------------------------------------------- /boeluem-4/zamanlayicilar-tickers.md: -------------------------------------------------------------------------------- 1 | # Zamanlayıcılar (Tickers) 2 | 3 | Golang’de **zamanlayıcılar**, belirli sürede bir tekrar etme işlemi için kullanılır. Zamanlayıcılar programın çalışma süresince veya durdurulana kadar çalışabilir. Örneğimizi görelim: 4 | 5 | ```go 6 | package main 7 | import ( 8 | "fmt" 9 | "time" 10 | ) 11 | func main() { 12 | tekrar := time.NewTicker(500 * time.Millisecond) // her yarım saniyede 1 13 | bitti := make(chan bool) 14 | go func() { 15 | for { 16 | select { 17 | case <-bitti: 18 | return 19 | case zaman := <-tekrar.C: 20 | fmt.Println("Tekrar zamanı:", zaman) 21 | } 22 | } 23 | }() 24 | time.Sleep(1600 * time.Millisecond) // 1,6 saniye programı uyut 25 | tekrar.Stop() // Durdurduk 26 | bitti <- true // for döngüsünü sonlandırdık. 27 | fmt.Println("Tekrarlayıcı durdu!") 28 | } 29 | ``` 30 | 31 | Açıklaması şöyledir:\ 32 | \ 33 | **tekrar** adında bir zamanlayıcı oluşturduk ve bu zamanlayıcının özelliği her **yarım saniyede bir** tetiklenmesi.\ 34 | \ 35 | **bitti** adında, boolean değer taşıyan bir kanal oluşturduk. Bu kanalın mantığı ileride anlayacaksınız.\ 36 | \ 37 | Anonim Goroutine fonksiyonunun içine, yani **go func()**, sınırsız döngü çeviren bir **for** oluşturduk. Bu döngünün içerisinde **select** ile kanal iletişimlerimizi dinledik. Döngümüzün sonlanması için **bitti** kanalına herhangi bir veri gelmesi gerekiyor. Aşağısındaki **case**‘de zaman değişkenimize tekrar zamanlayıcımız tetiklendikçe bu durum çalışacak. (tekrar.C ile zaman bilgisini alıyoruz.) Yani yarım saniyede bir zaman kanalına veri gelecek.\ 38 | \ 39 | Anonim Goroutine fonksiyonu, **main()** fonksiyonundan ayrı olarak çalıştığından bu fonksiyonumuzun çalışması için ona zaman aralığı vermemiz gerekiyor. **time.Sleep(1600 \* time.Millisecond)** ile **main()** fonksiyonumuzu 1,6 saniye bekletiyoruz. Bu bekleme süresi içinde tekrar zamanlayıcımız 3 kere tetikleniyor. (500 \* x < 1600 | x = 3) Haliyle de 3 kere ekrana çıktımızı bastırıyor. 1,6 saniye geçtikten sonra tekrar zamanlayımızı **tekrar.Stop()** ile durduruyoruz.\ 40 | \ 41 | **bitti** kanalına değer yollayarak, yukarıdaki **for** döngümüzü **return** ile sonlandırmış oluyoruz.\ 42 | \ 43 | Ve en son ekranımıza **“Tekrarlayıcı durdu!”** yazımızı bastırıyoruz.\ 44 | Çıktımız aşağıdaki gibi olacaktır: 45 | 46 | > Tekrar zamanı: 2019-10-15 14:08:02.002909142 +0300 +03 m=+0.500235484\ 47 | > Tekrar zamanı: 2019-10-15 14:08:02.502993622 +0300 +03 m=+1.000319851\ 48 | > Tekrar zamanı: 2019-10-15 14:08:03.002952074 +0300 +03 m=+1.500278387\ 49 | > Tekrarlayıcı durdu! 50 | -------------------------------------------------------------------------------- /boeluem-5/cok-satirli-string-olusturma.md: -------------------------------------------------------------------------------- 1 | # Çok Satırlı String Oluşturma 2 | 3 | Çok satırlı string oluşturmak için (\`) işaretini kullanırız. Türkçe klavyeden **alt gr** ve **virgül** tuşuna basarak bu işareti koyabilirsiniz. İşte örnek kodumuz; 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func main() { 9 | yazi := `Bu bir 10 | çok satırlı 11 | yazı örneğidir. 12 | ` 13 | fmt.Printf("%s", yazi) 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /boeluem-5/disa-aktarma-exporting.md: -------------------------------------------------------------------------------- 1 | # Dışa Aktarma (Exporting) 2 | 3 | Golang’ta dışa altarma çok basit bir olaydır. Diğer programlama dillerinde public anahtar kelimesi olarak gördüğümüz bu olayın Golang’ta nasıl yapıldığına bakalım. Golang’ta bunun için bir anahtar kelime yoktur. Dışa aktarılmasını istediğimiz öğeyi oluştururken baş harfini büyük yazarız. Örnek olarak: 4 | 5 | ```go 6 | func Topla(x, y int) int { 7 | return x + y 8 | } 9 | ``` 10 | 11 | Gördüğünüz gibi Topla() fonksiyonunun baş harfini büyük yazdır. Peki dışa aktarma hangi durumlarda yapılır. 12 | 13 | * Bir paket oluşturup başka bir paket içerisinden dışa aktarılan öğeyi kullanmak istiyorsak, 14 | * Projemiz birden fazla .go dosyası içeriyorsa ve bir sayfadaki öğeyi başka sayfada da kullanmak istiyorsak, 15 | 16 | dışa aktarma yöntemi işimizi görecektir.\ 17 | Fonksiyonları dışa aktarabildiğimiz gibi değişkenleri ve sabitleride dışa aktarbiliriz. Örnek olarak: 18 | 19 | ```go 20 | var Degisken = string("değişken değerimiz") 21 | const Sabit = string("sabit değerimiz") 22 | ``` 23 | 24 | Dışa aktarma olayı Golang’ta bu kadar basittir. 25 | -------------------------------------------------------------------------------- /boeluem-5/format-ve-kacis-karakterleri.md: -------------------------------------------------------------------------------- 1 | # Format ve Kaçış Karakterleri 2 | 3 | **Format Karakterleri ve Kullanım Alanları**\ 4 | Format karakterleri metinsel bir ifadede (string), dizgiyi formatlandırmak için kullanılır. Yani bir metinde değişken yerleri biçimlendirmeye yarar. 5 | 6 | | Format Karakteri | Açıklama | 7 | | ---------------- | ------------------------------------------------ | 8 | | %T | Değişkenin tipini verir | 9 | | %t | Boolean değeri verir | 10 | | %d | Int (tamsayı) değeri verir | 11 | | %b | Sayının binary (ikili) karşılığını verir | 12 | | %c | Karakter değerini verir | 13 | | %x | Sayının hexadecimal (onaltılı) karşılığını verir | 14 | | %f | Float (ondalıklı) değeri verir | 15 | | %s | String (dizgi-metin) değeri verir | 16 | | %v | Değeri otomatik belirler | 17 | 18 | Hemen bir örnek yapalım. 19 | 20 | ```go 21 | package main 22 | 23 | import "fmt" 24 | 25 | func main() { 26 | isim := "Kaan" 27 | yaş := 23 28 | kilo := 71.3 29 | evli := false 30 | 31 | fmt.Printf("İsim: %s, Yaş: %d, Kilo: %f, Evli: %t", isim, yaş, kilo, evli) 32 | } 33 | ``` 34 | 35 | Yukarıdaki kodlara göre şöyle bir çıktı alacaksınız: 36 | 37 | > İsim: Kaan, Yaş: 23, Kilo: 71.300000, Evli: false 38 | 39 | Kilo olarak girdiğimiz değer uzun olarak görüntülendi. Bunu değiştirmek için aşağıdaki yöntem uygulanır. 40 | 41 | ```go 42 | fmt.Printf("İsim: %s, Yaş: %d, Kilo: %.1f, Evli: %t", isim, yaş, kilo, evli) 43 | ``` 44 | 45 | Yukarıdaki kodda farkedeceğiniz üzere `kilo` değişkeni için olan format karakterini `%.1f` olarak değiştirdik. Bu küsüratlı sayılarda noktadan sonra 1 karakter gelebileceğini gösteriyor. Çıktımız: `71.3` olarak değişecektir. 46 | 47 | > İsim: Kaan, Yaş: 23, Kilo: 71.3, Evli: false 48 | 49 | {% hint style="warning" %} 50 | Format karakterleri **Printf** ve **Scanf** gibi fonksiyonlarda kullanılabilir. Bu fonksiyonların ortak özellikleri adında **f** harfi olmasıdır. 51 | {% endhint %} 52 | 53 | **Kaçış Karakterleri ve Kullanım Alanları**\ 54 | Kaçış karakterleri de format karakterleri gibi metinlere etki eder. Kaçış karakterlerini kod yazma zamanında yapamadığımız işlemler için kullanırız. 55 | 56 | | Kaçış Karakteri | Açıklama | 57 | | --------------- | --------------------------------------- | 58 | | \a | Komut satırında zil sesi çıkartır | 59 | | \b | Silme tuşu görevini görür | 60 | | \f | Merdiven metin yazar | 61 | | \n | Yeni satıra geçer | 62 | | \r | Return eder | 63 | | \t | Tab tuşu gibi boşluk bırakır (4 boşluk) | 64 | | \v | Dikey boşluk bırakır | 65 | | \\ | Ters-taksim yazar | 66 | | \\' | Tek tırnak yazar | 67 | | \\" | Çift tırnak yazar | 68 | 69 | Gelelim örneğimize: 70 | 71 | ```go 72 | fmt.Print("Bir\nİki\tÜç\\Dört") 73 | ``` 74 | 75 | Çıktımız şöyle olacaktır: 76 | 77 | > Bir\ 78 | > İki Üç\Dört 79 | -------------------------------------------------------------------------------- /boeluem-5/golangte-kullanicidan-giris-alma.md: -------------------------------------------------------------------------------- 1 | # Golang'te Kullanıcıdan Giriş Alma 2 | 3 | Golang’te diğer programlama dillerinde de olduğu gibi kullanıcıdan değer girişi alınabilir. Böylece programımızı interaktif hale getirmiş oluruz. 4 | 5 | \ 6 | **Scan() Fonksiyonu**\ 7 | Bu fonksiyon boşluğa kadar olan kelimeyi kaydeder. Yeni satır boşluk olarak sayılır. Kullanımını görelim. 8 | 9 | ```go 10 | var yazi string 11 | fmt.Scan(&yazi) //yazi değişkenine değer girilmesini istedik. 12 | fmt.Println(“\n”+yazi) 13 | ``` 14 | 15 | Yukarıda yazdığımız kodları inceleyecek olursak, belleğe yazi isimli string türünde bir değişken kaydettik. Kullanıcının girişte bulunabilmesi için **Scan()** fonksiyonunu kullandık. Bu fonksiyonun içerisine **\&yazi** yazdık. Bu sayede kullanıcının girdiği değer **yazi** değişkeninin içerisine kaydedilebilecek. Daha sonra **yazi** değişkenini ekrana bastırdık ve bizim yazdığımız değer görüntülendi. Scan fonksiyonunda dikkat edilmesi gereken nokta kullanıcı istediği kadar kelime girse bile programın ilk kelimeyi değer olarak alacağıdır. **Scan()** fonksiyonu boş giriş kabul etmez. 16 | 17 | **Scanf() Fonksiyonu**\ 18 | **Scanf()** fonksiyonu **Printf()** fonksiyonu gibi format içerir. Bu fonksiyon ile kullanıcının girişini bölüp birkaç değişkene kaydedebiliriz. Hemen kullanımını görelim. 19 | 20 | ```go 21 | var kelime1, kelime2 string 22 | fmt.Scanf(“%s %s”,&kelime1,&kelime2) 23 | fmt.Println(kelime1) 24 | fmt.Println(kelime2) 25 | ``` 26 | 27 | Yukarıda yazdığımız kodları inceleyecek olursak, **kelime1** ve **kelime2** adında **string** türünde değişkenler belirledik. **Scanf()** fonksiyonu ile **Printf()**’den benzer olarak, değişkenlerin yerleştirileceği yerleri değil de, bu sefer değişkenlerin alınacağı yerleri belirtiyoruz. **%s %s** arasındaki **boşluk** sayesinden kullanıcı boşluk bırakınca girdiyi **2** değere bölebileceğiz. Hemen yanında ise içine atanacak değişkenlerimizi belirtiyoruz. Böylelikle kullanıcı giriş bölümünden Go Dili yazdığında **Go**’yu **kelime1**’in içine **Dili** de **kelime2** içine yerleştirecek. **Scanf()**, boş giriş kabul eder. 28 | 29 | **Reader ile Satır Olarak Değer Alma**\ 30 | Aşağıdaki yöntem ile bir satır yazıyı giriş olarak alabilirsiniz. 31 | 32 | ```go 33 | giris := bufio.NewReader( os.Stdin) 34 | yazi, _ := giris.ReadString('\n') 35 | ``` 36 | 37 | {% hint style="info" %} 38 | **Scan** komutu ile kelime alamadığınızda **Reader** ile deneyebilirsiniz. 39 | {% endhint %} 40 | -------------------------------------------------------------------------------- /boeluem-5/import-kuetuephane-ekleme-yoentemleri.md: -------------------------------------------------------------------------------- 1 | # Import (Kütüphane Ekleme) Yöntemleri 2 | 3 | Bu yazıda sizlere Golang’ta paket import etmenin tüm yöntemlerini göstereceğim.\ 4 | **1. Yöntem** 5 | 6 | ```go 7 | import "fmt" 8 | ``` 9 | 10 | **fmt** paketini import ettik.\ 11 | **2. Yöntem** 12 | 13 | ```go 14 | import ( 15 | "fmt" 16 | "net/http" 17 | ) 18 | ``` 19 | 20 | Birden fazla paket import ettik\ 21 | **3. Yöntem** 22 | 23 | ```go 24 | import f "fmt" 25 | ``` 26 | 27 | **fmt** paketini import edip **f** olarak kullanacağımızı belirttik. Örnek olarak **fmt.Println()** yazmak yerine **f.Println()** yazacağız.\ 28 | **4. Yöntem** 29 | 30 | ```go 31 | import . "fmt" 32 | ``` 33 | 34 | Dikkat ederseniz, **import** kelimesinden sonra **nokta** koyduk. Bu işlem sayesinde **fmt.Println()** yazmak yerine sadece **Println()** yazarak aynı işi yapmış oluruz.\ 35 | **5. Yöntem** 36 | 37 | ```go 38 | import _ "fmt" 39 | ``` 40 | 41 | Bazen Golang yazarken kütüphaneyi ekleyip kullanmadığımız zamanlar olur. Böyle durumlarda program çalıştırılırken veya derlenirken kullandığınız editör veya ide bu bölümü silebilir. import ederken **\_ (alt tire)** koyarak bunun üstesinden gelebiliriz. 42 | -------------------------------------------------------------------------------- /boeluem-5/init-fonksiyonu-oen-yuekleme.md: -------------------------------------------------------------------------------- 1 | # init() Fonksiyonu (Ön Yükleme) 2 | 3 | Golang’te bir uygulama çalışırken genelde çalışan ilk fonksiyon **main()** fonksiyonu oluyor. Bazen programın açılışında ayarlamamız gereken ön durumlar oluşuyor. İşte **init()** fonksiyonu bize bu imkanı sunuyor. Ufak bir örnekle yazdıklarıma anlam katalım. 4 | 5 | ```go 6 | package main 7 | import "fmt" 8 | func init() { 9 | fmt.Println("init fonksiyonu yüklendi") 10 | } 11 | func main() { 12 | fmt.Println("main Fonksiyonu yüklendi") 13 | } 14 | ``` 15 | 16 | Çıktımız aşağıdaki gibi olacaktır. 17 | 18 | > init fonksiyonu yüklendi\ 19 | > main Fonksiyonu yüklendi 20 | 21 | Golang’taki **init()** fonksiyonunun kullanımı, farklı dillerdeki aynı işlevi gören fonksiyonlara oranla daha kolaydır. Örnek olarak **init()** fonksiyonunda veritabanı bağlantımızı, kayıt defteri işlemlerimizi veya sadece bir kez yapmamız gereken işleri yapabiliriz. Buna imkan sağlayan mantığı aşağıdaki örnekte görelim. Bu örnekte global tanımlanmış değişkenin değerini **init()** fonksiyonunda değiştirdiğimizde **main()** gibi farklı fonksiyonlarda kullanabildiğimizi göreceğiz. 22 | 23 | ```go 24 | package main 25 | import "fmt" 26 | var değişken string 27 | func init() { 28 | değişken = "Merhaba Dünya" 29 | } 30 | func main() { 31 | fmt.Println(değişken) 32 | } 33 | ``` 34 | 35 | Çıktımız ise şöyle olacaktır. 36 | 37 | > Merhaba Dünya 38 | 39 | İşte **init()** fonksiyonunun böyle bir güzelliği var. Benzer bir işlevi ancak pointers (işaretçiler) ile yapabiliriz. 40 | 41 | ```go 42 | package main 43 | import "fmt" 44 | var değişken string = "Naber" 45 | func değiştir(değişken *string) { 46 | *değişken = "Merhaba Dünya" 47 | } 48 | func main() { 49 | değiştir(&değişken) 50 | fmt.Println(değişken) 51 | } 52 | ``` 53 | 54 | O da gördüğünüz gibi uzun bir işlem oluyor. 55 | -------------------------------------------------------------------------------- /boeluem-5/panic-and-recover.md: -------------------------------------------------------------------------------- 1 | # Panic & Recover 2 | 3 | **Panic** ve **Recover**, Golang’de hata ayıklama için kullanılan anahtar kelimelerdir. Size bunu daha iyi ve akılda kalıcı anlatmak için teorik anlatım yerine uygulamalı öğretim yapmak istiyorum. Böylece daha akılda kalıcı olur.\ 4 | Aşağıda **panic** durumu oluşturan bir örnek göreceğiz: 5 | 6 | ```go 7 | package main 8 | func main() { 9 | sayilar := make([]int, 5) 10 | sayilar[6] = 10 11 | } 12 | ``` 13 | 14 | Yukarıda **make** fonksiyonu ile **sayilar** adında uzunluğu **5** birimden oluşan bir **int** dizi oluşturduk. Bu bildiğimiz sayısal 5 tane değişken tutan bir dizi aslında. Ama altında **sayilar** dizisinin **6**. indeksine **10** değerini atamak istedik. Fakat **sayilar** dizesinin 6. indeksi mantıken bulunmamakta. Bu haldeyken programımız **panic** hatası verecektir ve çıktımız aşağıdaki gibi olacaktır. 15 | 16 | > panic: runtime error: index out of range\ 17 | > goroutine 1 \[running]:\ 18 | > main.main()\ 19 | > /home/ksc10/Desktop/deneme/main.go:5 +0x11\ 20 | > exit status 2 21 | 22 | İstersek biz de kritik bir bilginin nil girilmesi gibi durumlarda programı durdurabiliriz. Bunun için **panic()** fonksiyonunu kullanacağız. Hemen bir örnek yapalım. 23 | 24 | ```go 25 | package main 26 | 27 | import ( 28 | "fmt" 29 | ) 30 | 31 | func TamIsim(Ad *string, Soyad *string) { 32 | if Ad == nil { 33 | panic("Ad nil olamaz") 34 | } 35 | if Soyad == nil { 36 | panic("Soyad nil olamaz") 37 | } 38 | fmt.Printf("%s %s\n", *Ad, *Soyad) 39 | fmt.Println("TamIsim fonksiyonu bitti") 40 | } 41 | 42 | func main() { 43 | Ad := "Yusuf" 44 | TamIsim(&Ad, nil) 45 | fmt.Println("Ana fonksiyon da bitti") 46 | } 47 | ``` 48 | 49 | Çıktımız burada: 50 | 51 | > panic: Soyad nil olamaz\ 52 | > goroutine 1 \[running]:\ 53 | > main.TamIsim(0xc00007df30, 0x0)\ 54 | > /Users/Y/Desktop/main.go:12 +0x19a\ 55 | > main.main()\ 56 | > /Users/Y/Desktop/main.go:20 +0x65\ 57 | > exit status 2 58 | 59 | Burada **Soyad** değişkeni tanımsız olduğu için programımız durdu. Aynı şekilde **recover()** fonksiyonu ile **panic()** fonksiyonundan gelen veriyi alabilir, ana fonksiyonumuzun kapanmasına da engel olabiliriz. Bunun için de bir örnek yapalım. 60 | 61 | ```go 62 | package main 63 | 64 | import ( 65 | "fmt" 66 | ) 67 | 68 | func TamIsim(Ad *string, Soyad *string) { 69 | if Ad == nil { 70 | panic("Ad nil olamaz") 71 | } 72 | if Soyad == nil { 73 | panic("Soyad nil olamaz") 74 | } 75 | fmt.Printf("%s %s\n", *Ad, *Soyad) 76 | fmt.Println("TamIsim fonksiyonu bitti") 77 | } 78 | 79 | func main() { 80 | Ad := "Yusuf" 81 | defer func() { 82 | if r := recover(); r != nil { 83 | fmt.Println("Panik Yok : ", r) 84 | } 85 | }() 86 | TamIsim(&Ad, nil) 87 | fmt.Println("Ana fonksiyon da bitti") 88 | } 89 | ``` 90 | 91 | Çıktımız burada : 92 | 93 | > Panik Yok : Soyad nil olamaz 94 | -------------------------------------------------------------------------------- /boeluem-5/print-fonksiyonu-birkac-inceleme.md: -------------------------------------------------------------------------------- 1 | # Print Fonksiyonu Birkaç İnceleme 2 | 3 | Print fonksiyonu Go dilinde komut satırı üzerinde yazdırma işlemi yapmak için kullanılır. Print fonksiyonunun en çok kullanılan 3 çeşidine bakalım. 4 | 5 | **Print() Fonksiyonu**\ 6 | Bu fonksiyonun içine parametreler girerek ekrana yazdırma işlemi yapabiliriz. 7 | 8 | ```go 9 | fmt.Print(“Merhaba Dünya!”) 10 | ``` 11 | 12 | Çıktımız şu şekilde olacaktır: 13 | 14 | > Merhaba Dünya 15 | 16 | **Println() Fonksiyonu**\ 17 | Bu fonksiyon ile içine parametre girerek ekrana yazdırma işlemi yapabiliriz. Yazdırma işlemi yaptıktan sonra bir alt satıra geçer. 18 | 19 | ```go 20 | fmt.Println(“satır1”) 21 | fmt.Println(“satır2”) 22 | ``` 23 | 24 | Çıktımız şu şekilde olacaktır; 25 | 26 | > satır1\ 27 | > satır2 28 | 29 | **Printf() Fonksiyonu**\ 30 | Gelelim işimizi görecek olan Printf() fonksiyonuna. Bu fonksiyon sayesinde metinsel bölümlerin arasına değişken yerleştirebiliriz. 31 | 32 | ```go 33 | dil:=”Go” 34 | yıl:=2007 35 | fmt.Printf(“%s dili %d yılından beri geliştiriliyor.”,dil,yıl) 36 | ``` 37 | 38 | Çıktımız şu şekilde olacaktır; 39 | 40 | > Go dili 2007 yılından beri geliştiriliyor. 41 | -------------------------------------------------------------------------------- /boeluem-5/sprintf.md: -------------------------------------------------------------------------------- 1 | # Sprintf 2 | 3 | Sprintf fonksiyonu fmt paketine dahil bir fonksiyondur. Bu fonksiyon değişkenlere formatlı atama yapmamıza yardımcı olur. Örneğimizi görelim: 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | func main() { 13 | isim := "Kaan" 14 | 15 | isimTip := fmt.Sprintf("isim değişkeni %T tipindedir.", isim) 16 | 17 | fmt.Println(isimTip) 18 | } 19 | ``` 20 | -------------------------------------------------------------------------------- /boeluem-5/testing-test-etme.md: -------------------------------------------------------------------------------- 1 | # Testing (Test Etme) 2 | 3 | Hücrelerin vücumudaki yapı birimi olduğu gibi, aynı şekilde her bileşen de yazılımın birer parçasıdır. Yazılımın sağlıklı bir şekilde çalışabilmesi için, her bileşenin güvenilir bir şekilde çalışması gerekir.\ 4 | Aynı şekilde vücudumuzun sağlığı hücrelerin güvenilirliği ve verimliliğine bağlı olduğu gibi, yazılımın düzgün çalışması bileşenlerin güvenilirliği ve verimliliğine bağlıdır.\ 5 | Biraz biyoloji dersi gibi oldu ama sonuçta aynı mantığı yürütebiliriz. 6 | 7 | **Peki bileşenler nedir?**\ 8 | Yazılımın çalışması için yazılmış her bir kod parçasına denir. Bu bileşenlerin yazılımımızın sağlıklı bir şekilde çalıştırdığından emin olmamız gerekir.\ 9 | Peki bu bileşenlerin sağlamlık kontrolünü nasıl gerçekleştiririz? Tabiki **test** ederek.\ 10 | Bir test aşamsının Golang’ta nasıl göründüğünü görelim. 11 | 12 | ```go 13 | import "testing" 14 | func TestFunc(t *testing.T){ 15 | t.error() //testin başarısız olduğunu bildirir. 16 | } 17 | ``` 18 | 19 | Yukarıdaki işlem Golang’ta yapılan bir birim testin temel yapısıdır. Yerleşik **testing** paketi, Golang’ın standart paketleri içerisinde gelir. Birim testi, **\*testing.T** türündeki elemanı kabul eden ve bu elemanı göre hata yayınlayan bir bir işlemdir.\ 20 | Bu fonksiyonların adı büyük harfle başlamalı ve birleşik olan adın devamı da büyük harfle başlamalıdır. Yani **camel-case** olmalıdır.\ 21 | `TestFunc olmalıdır ve Testfunc olmamalıdır.`\ 22 | Uygulama örneğimize geçelim.\ 23 | Bir proje klasörü oluşturalım ve **main.go** dosyamız şöyle olsun. 24 | 25 | ```go 26 | package main 27 | import "fmt" 28 | func Merhaba(isim string) (çıktı string) { 29 | çıktı = "Merhaba " + isim 30 | return 31 | } 32 | func main() { 33 | selamla := Merhaba("Kaan") 34 | fmt.Println(selamla) 35 | } 36 | ``` 37 | 38 | **main.go** dosyamızda fonksiyona adını girdiğimiz kişiyi selamlıyor. Buraya kadar gayet basit bir program. Fonksiyonlarımızı test edeceğimiz için baş harflerini büyük yazmayı unutmuyoruz. Böylelikle fonksiyonlarımızı dışarı aktarabiliriz. Test fonksiyonumuzun çalışma mantığını görmek için **main\_test.go** dosyamıza bakalım. 39 | 40 | ```go 41 | package main 42 | import "testing" 43 | func TestMerhaba(t *testing.T) { 44 | if Merhaba("Kaan") != "Merhaba Kaan" { 45 | t.Error("Merhaba Fonksiyonunda bir sıkıntı var!") 46 | } 47 | } 48 | ``` 49 | 50 | Yukarıda ise **main.go** sayfamızdaki **Merhaba** fonksiyonunu test etmek için **TestMerhaba** adında fonksiyon oluşturduk. **t \*testing.T** ibaresi ile bu işlemin test etmeye yönelik bir işlem olduğunu belirttik.\ 51 | Fonksiyonun içerisine baktığımızda, **Merhaba(“Kaan”)** işleminin sonucu **“Merhaba Kaan”** olmadığı zaman test hatası vermesini istedik. Ve gözükecek hatayı belirttik.\ 52 | Test işlemi yapmak için aşağıdaki komutları komut satırına yazıyoruz. 53 | 54 | > go test 55 | 56 | Yukarıdaki yazdığımız kodlara göre şöyle bir çıktımızın olması gerekir. 57 | 58 | > PASS ok\ 59 | > \_/home/ksc10/Desktop/deneme 0.002s 60 | 61 | Eğer **TestMerhaba** fonksiyonunda test koşuluna **“Merhaba Kaan”** yerine **“Merhaba Ahmet”** yazsaydık, aşağıdaki gibi bir **go test** çıktımız olurdu. 62 | 63 | > \--- FAIL: TestMerhaba (0.00s)\ 64 | > main\_test.go:7: Merhaba Fonksiyonunda bir sıkıntı var!\ 65 | > FAIL\ 66 | > exit status 1\ 67 | > FAIL \_/home/ksc10/Desktop/deneme 0.002s 68 | 69 | **Go Test Komutları** 70 | 71 | | Komut | Açıklama | 72 | | ------------------------ | ----------------------------------------------------------------- | 73 | | go test | İçerisinde bulunduğu projenin tüm test fonksiyonlarını test eder. | 74 | | go test -v | Her test için ayrı bilgi verir. | 75 | | go test -timeout 30s | 30 saniye zaman aşımı ile test eder. | 76 | | go test -run TestMerhaba | Sadece belirli bir fonksiyonu test eder. | 77 | 78 | **Örnek kullanımı:**\ 79 | **main\_test.go** dosyamızdaki **TestMerhaba** fonksiyonumuzu **10 saniye** zaman aşımı ile test edecek komut 80 | 81 | > go test -timeout 30s -run TestMerhaba 82 | 83 | Bu yazımızda Golang’de test işleminin nasıl yapıldığını gördük. Mantığını daha iyi kavramak için bir proje üzerinde gerekli olduğu yerde kullanmamız gerekir. 84 | -------------------------------------------------------------------------------- /boeluem-6-paketler/komut-satiri-arguemanlari-args.md: -------------------------------------------------------------------------------- 1 | # Komut Satırı Argümanları (Args) 2 | 3 | Golang ile programlarımızın komut satırı üzerinden argümanlar ile çalışmasını sağlayabiliriz. İşte paketimiz: 4 | 5 | ``` 6 | import "os" 7 | ``` 8 | 9 | `os` paketimizdeki `Args` fonksiyonu bize string dizi sunar. **** Bir örnek görelim. 10 | 11 | ```go 12 | package main 13 | 14 | import ( 15 | "fmt" 16 | "os" 17 | ) 18 | 19 | func main() { 20 | for i, arg := range os.Args { 21 | fmt.Println(i, "=", arg) 22 | } 23 | } 24 | ``` 25 | 26 | `for-range` ile `os.Args`'ın uzunluğu kadar işlem yapıyoruz ve içerisindekileri indeksi ile ekrana bastırıyoruz. Şöyle bir çıktımız oluyor: 27 | 28 | > ./main naber nasılsın 29 | > 30 | > 0 = ./main\ 31 | > 1 = naber\ 32 | > 2 = nasılsın 33 | -------------------------------------------------------------------------------- /boeluem-6-paketler/komut-satiri-bayraklari-flags.md: -------------------------------------------------------------------------------- 1 | # Komut Satırı Bayrakları (Flags) 2 | 3 | Komut satırı bayrakları, örnek olarak; 4 | 5 | > ./uygulamamız -h 6 | 7 | Sondaki `-h` bir flag(bayrak)’dir. Örnek bir program yazalım. 8 | 9 | ```go 10 | package main 11 | import ( 12 | "flag" 13 | "fmt" 14 | ) 15 | func main() { 16 | kelime := flag.String("kelime", "varsayılan kelime", "metin tipinde") 17 | sayi := flag.Int("sayi", 1881, "sayı tipinde") 18 | mantiksal := flag.Bool("mantiksal", false, "boolean tipinde") 19 | flag.Parse() 20 | fmt.Println("kelime:", *kelime) 21 | fmt.Println("sayi:", *sayi) 22 | fmt.Println("mantiksal:", *mantiksal) 23 | } 24 | ``` 25 | 26 | Gelelim açıklamasına;\ 27 | **kelime** isminde **string** tipinde bir flag oluşturduk. **flag.String()** fonksiyonu içerisinde 1. parametre komut satırından **“-kelime”** argümanıyla gireceğimizi gösteriyor. Varsayılan değeri **“varsayılan kelime”** olacak ve açıklama bölümünde **“metin tipinde”** yazacak.\ 28 | **sayi** isminde **int** tipinde bir flag oluşturduk. **flag.Int()** fonksiyonu içerisinde komut satırından **“-sayi”** argümanıyla gireceğimizi belirttik. Varsayılan değeri **1881** olacak ve açıklama bölümünde **“sayı tipinde”** yazacak.\ 29 | **mantiksal** isminde **bool** tipinde bir flag oluşturduk. **flag.Bool()** fonksiyonunda **“-mantiksal”** argumanıyla çağırılacağını belirttik. Varsayılan değeri **false** olacak ve açıklama bölümünde **“boolean tipinde”** yazacak.\ 30 | Uygulamamızı build edelim ve ismi **uygulama** olsun. 31 | 32 | > go build -o ./uygulama . 33 | 34 | Windows için build ediyorsanız, `./uygulama` yerine `./uygulama.exe` yazarak build edin. (Hatırlatma yapayım dedim) Build ettikten sonra örnek bir kullanımını yapalım. 35 | 36 | > ./uygulama -kelime=Atatürk -sayi=1881 -mantiksal=true 37 | 38 | Çıktımız şu şekilde olacaktır. 39 | 40 | > kelime: Atatürk\ 41 | > sayi: 1881\ 42 | > mantiksal: true 43 | 44 | Peki bu girdiğimiz flag açıklamaları ne oluyor diye soracak olursanız eğer, onu da aşağıdaki komutu yazarak görebilirsiniz. 45 | 46 | > ./uygulama -h 47 | 48 | Çıktımız şu şekilde olacaktır. 49 | 50 | > Usage of ./uygulama:\ 51 | > \-kelime string\ 52 | > metin tipinde (default "varsayılan kelime")\ 53 | > \-mantiksal\ 54 | > boolean tipinde (default false")\ 55 | > \-sayi int\ 56 | > sayı tipinde (default 1881) 57 | -------------------------------------------------------------------------------- /boeluem-6-paketler/paket-kuetuephane-yazmak.md: -------------------------------------------------------------------------------- 1 | # Paket (Kütüphane) Yazmak 2 | 3 | Bu bölümde Go üzerinde nasıl kendi paketimizi (kütüphanemizi) oluşturacağımıza bakacağız. 4 | 5 | ### Bir Paketin Özellikleri 6 | 7 | * İçerisinde `.go` dosyaları bulunan bir klasördür. 8 | * Diğer projeler tarafından içe aktarılabilir. 9 | * Dışa aktarılabilen veya aktarılamayan veriler içerir. 10 | * Açık kaynaktır. 11 | * `main()` fonksiyonu içermez. 12 | * `package main` değildir. 13 | 14 | Paket oluştururken dikkat etmemiz gereken prensipler vardır. Bunlar şık ve basit kod yazımı, dışarıdan kullanımı basit, mümkün olduğunca diğer paketlere bağımsız olmasıdır. Bu prensiplere dikkat ederek daha iyi bir paket yazabilirsiniz. 15 | 16 | ### Proje Klasöründe Yerel Kütüphane Oluşturma 17 | 18 | Öncelikle aşağıdaki gibi bir dosya düzenimiz olduğunu varsayalım. 19 | 20 | ![Proje Klasörümüzün Yapısı](../.gitbook/assets/package.png) 21 | 22 | Yukarıdaki gibi `paketim` klasörü içerisinde `paketim.go` dosyamız olsun. 23 | 24 | `paketim.go` dosyamızın içi aşağıdaki gibi olsun. 25 | 26 | ```go 27 | package paketim 28 | 29 | import "fmt" 30 | 31 | func Yaz() { 32 | fmt.Println("yazdım!") 33 | } 34 | ``` 35 | 36 | `package paketim` ile paketimizin ismini belirledik. Bu isim paket klasörümüz ile aynı olmalıdır. Daha sonra projemizde kullanabilmemiz için dışa aktarılmış şekilde `Yaz()` fonksiyonu oluşturduk. Bu fonksiyonun ne işe yaradığı zaten belli. 37 | 38 | `main.go` dosyamız ise aşağıdaki gibi olsun. 39 | 40 | ```go 41 | package main 42 | 43 | import p "./paketim" 44 | 45 | func main() { 46 | p.Yaz() 47 | } 48 | ``` 49 | 50 | `import p "./paketim"` yazarak özel paketimizin yerel konumunu belirterek, `p` lakabı (alias) ile çağırdık. 51 | 52 | `Yaz()` fonksiyonumuzu ise `p.Yaz()` şeklinde kullandık. 53 | 54 | ### Git Sisteminde Kütüphane Paylaşımı 55 | 56 | Oluşturduğumuz kütüphaneyi Github, Gitlab, Bitbucket vb. sitelerde barındırarak diğer geliştiricilerinde kütüphanelerinizden faydalanmasını sağlayabilirsiniz. 57 | 58 | Bunun için kütüphanenizin isminde bir repo oluşturup, içerisinde Go dosyalarınızı yükleyin. Daha sonra `go get github.com/id/repoismi` şeklinde projenize import edebilirsiniz. 59 | -------------------------------------------------------------------------------- /boeluem-6-paketler/regexp-kuralli-ifadeler.md: -------------------------------------------------------------------------------- 1 | # Regexp (Kurallı İfadeler) 2 | 3 | **Regular Expressions (Regexp)**, modern programlama dillerinin neredeyse hepsinde bulunan metinsel ifadelerinizin yapısını kontrol etmenizi sağlayan bir pakettir. 4 | 5 | Bu paket sayesinde yazdığımız programda ifadelerin uygunluğunu kontrol edebilir, işimize yarayacak ifade/ifadeleri daha kolay ayırabilir ve giriş yapılan ifadeleri uygun bir düzene koyabiliriz. 6 | 7 | Örneğimizi görelim 8 | 9 | ```go 10 | package main 11 | 12 | import ( 13 | "fmt" 14 | "regexp" 15 | ) 16 | 17 | func main() { 18 | var isimKontrol = regexp.MustCompile(`^[a-z]+[0-9]$`) 19 | 20 | fmt.Println(isimKontrol.MatchString("kaan10")) //false 21 | fmt.Println(isimKontrol.MatchString("emir6")) //true 22 | fmt.Println(isimKontrol.MatchString("gokhan")) //false 23 | fmt.Println(isimKontrol.MatchString("Altan2")) //false 24 | fmt.Println(isimKontrol.MatchString("8erkay")) //false 25 | } 26 | ``` 27 | 28 | Öncelikle yukarıdaki işlemleri yapabilmemiz için, projemizde `"regexp"` paketini çağırmamız gerekiyor. 29 | 30 | `isimKontrol` adında bir değişken oluşturduk ve bu değişkenimizde `MustCompile()` fonksiyonu ile metinsel ifademizin kurallarını belirledik. 31 | 32 | Belirlediğimiz kural ise dizgimizin küçük harflerle a'dan z'ye kadar ve ek olarak 0'dan 9'a kadar **"rakamsal"** ifade alabileceğidir. Bu kurala uyulması için metinsel ifade ne eksik ne fazla hiçbir şey olmaması gerekir. 33 | 34 | Kuralımızın hemen aşağısındaki örnekte ise `"kaan10"` ifadesinde sadece 0-9 arası rakam (tek haneli) olması gerektiği için `false` çıktısını verdi. 35 | 36 | `"emir6"` ifade belirttiğimiz kurala uygun bir ifade olduğu için `true` çıktısını verdi. 37 | 38 | `"gokhan"` ifadesi içerisinde sayı barındırmadığı için `false` çıktısını verdi. 39 | 40 | `"Altan2"` ifadesi büyük harf ile başladığı için `false` çıktısını verdi. 41 | 42 | `"8erkay"` ifadesi ise rakam sonda olması gerekirken başta olduğu için `false` çıktısını verdi. 43 | 44 | Bu yazıda regexp nasıl yazılırdan ziyade Go'da regexp'in kullanımını anlatmak istediğimden bu kısmı kısa tutuyorum. Regexp'in nasıl yazıldığına göz atmak isteyenler için aşağıda linkini paylaşıyorum. Buyursunlar: 45 | 46 | {% embed url="https://ceaksan.com/tr/regex-regular-expressions-nedir" %} 47 | 48 | Bu güzel anlatım için [Ceyhun Enki Aksan](https://ceaksan.com/)'a ayrıca teşekkür ederim. 49 | -------------------------------------------------------------------------------- /boeluem-6-paketler/sort-siralama.md: -------------------------------------------------------------------------------- 1 | # Sort (Sıralama) 2 | 3 | Golang’ta dizilerin içeriğini sıralaya bileceğimiz bütünleşik olarak gelen **“sort**” isminde bir paket mevcuttur. Bu paketin kullanımı oldukça kolaydır. Örneğimizi görelim. 4 | 5 | ```go 6 | package main 7 | import ( 8 | "fmt" 9 | "sort" 10 | ) 11 | func main() { 12 | yazilar := []string{"c", "a", "b"} 13 | sort.Strings(yazilar) 14 | fmt.Println("Yazılar:", yazilar) 15 | sayilar := []int{7, 2, 4} 16 | sort.Ints(sayilar) 17 | fmt.Println("Sayılar:", sayilar) 18 | yazisirali := sort.StringsAreSorted(yazilar) 19 | fmt.Println("Yazılar Sıralandı mı?: ", yazisirali) 20 | sayisirali := sort.IntsAreSorted(sayilar) 21 | fmt.Println("Sayılar Sıralandı mı?:", sayisirali) 22 | } 23 | ``` 24 | 25 | Gelelim açıklamasına;\ 26 | Sıralama özelliğini kullanabilmek için **“sort”** paketini içe aktardık. **main()** fonksiyonumuzun içini inceleyelim.\ 27 | **yazilar** isminde içerisinde rastgele harflereden oluşan bir **string** dizi oluşturduk. Hemen aşağısında **sort.Strings(yazilar)** diyerek sıralamanın **string** türünde olduğunu belirterek sıralamamızı yaptık. Altında **yazilar** değişkenimizi ekrana bastırdık. 28 | 29 | **sayilar** isminde içerisinde rastgele sayılar olan **int** tipinde bir dizi oluşturduk. Hemen aşağısında **sort.Ints(sayilar)** diyerek **int** tipinde sıralamamızı yaptık. Altında **sayilar** değişkenimizi ekrana bastırdık.\ 30 | Dizilerin sıralı olup olmadığını öğrenmek için de aşağıdaki işlemleri yaptık.\ 31 | **yazisirali** değişkeninde **sort.StringsAreSorted(yazilar)** fonksiyonu ile **yazilar** dizisinin sıralı olup olmama durumuna göre **bool** değer aldık. Ve sonucu ekrana bastırdık.\ 32 | 33 | 34 | **sayisirali** değişkeninde **sort.IntsAreSorted(sayilar)** fonksiyonu ile **sayilar** dizisinin sıralı olup olmama durumuna göre **bool** değer aldık. Ve sonucu ekrana bastırdık.\ 35 | Yukarıdaki işlemlere göre çıktımız şu şekilde olacaktır. 36 | 37 | > Yazılar: \[a b c]\ 38 | > Sayılar: \[2 4 7]\ 39 | > Yazılar Sıralandı mı?: true\ 40 | > Sayılar Sıralandı mı?: true 41 | -------------------------------------------------------------------------------- /boeluem-6-paketler/strconv-string-ceviri.md: -------------------------------------------------------------------------------- 1 | # Strconv (String Çeviri) 2 | 3 | **strconv** paketi Golang ile bütünleşik gelen string tipi ve diğer tipler arasında çevirme işlemi yapabileceğimiz bir pakettir.\ 4 | 5 | 6 | İlk olarak `“strconv”` paketimizi içe aktarıyoruz.\ 7 | Aşağıda örnek kullanımılarını ve daha açıklayıcı olması için yanlarına kullanım amaçlarını yazdım. 8 | 9 | ```go 10 | package main 11 | import ( 12 | "fmt" 13 | "strconv" 14 | ) 15 | func main() { 16 | //basit string-int arası çevirme 17 | sayi, _ := strconv.Atoi("-42") //string > int 18 | yazi := strconv.Itoa(-42) //int > string 19 | //string'ten diğerlerine çevirme 20 | b, _ := strconv.ParseBool("true") //string > bool 21 | f, _ := strconv.ParseFloat("3.1415", 64) //string > float 22 | i, _ := strconv.ParseInt("-42", 10, 64) //string > int 23 | u, _ := strconv.ParseUint("42", 10, 64) //string > uint 24 | //diğerlerinden string'e çevirme 25 | s1 := strconv.FormatBool(true) //bool > string 26 | s2 := strconv.FormatFloat(3.1415, 'E', -1, 64) //float > string 27 | s3 := strconv.FormatInt(-42, 16) //int > string 28 | s4 := strconv.FormatUint(42, 16) //uint > string 29 | //Ekrana Yazdırma 30 | fmt.Printf("sayi: %d tip: %T\n", sayi, sayi) 31 | fmt.Printf("yazi: %s tip: %T\n", yazi, yazi) 32 | fmt.Printf("b: %t tip: %T\n", b, b) 33 | fmt.Printf("f: %f tip: %T\n", f, f) 34 | fmt.Printf("i: %d tip: %T\n", i, i) 35 | fmt.Printf("u: %d tip: %T\n", u, u) 36 | fmt.Printf("%T %T %T %T", s1, s2, s3, s4) 37 | } 38 | ``` 39 | 40 | Çıktımız şu şekilde olacaktır. 41 | 42 | > sayi: -42 tip: int\ 43 | > yazi: -42 tip: string\ 44 | > b: true tip: bool\ 45 | > f: 3.141500 tip: float64\ 46 | > i: -42 tip: int64\ 47 | > u: 42 tip: uint64\ 48 | > string string string string 49 | -------------------------------------------------------------------------------- /boeluem-6-paketler/strings.md: -------------------------------------------------------------------------------- 1 | # Strings 2 | 3 | Strings paketi ile **string** türünde değerler üzerinde işlemler yapabiliriz. Kısaca kullanımlarından bahsedelim.\ 4 | 5 | 6 | **Strings.Contains() Fonksiyonu**\ 7 | **Contains()** fonksiyonu ile istediğimiz bir string değerin içerisinde istediğimiz bir **string** değerin olup olmadığını kontrol edebiliriz. **Boolean** değer verir. Eğer varsa **true** değer döndürür. Yoksa **false** değer döndürür. Ufak bir uygulama örneği yapalım. 8 | 9 | ```go 10 | package main 11 | import ( 12 |  "fmt" 13 |  "strings" 14 | ) 15 | func main() { 16 |  var eposta string 17 |  fmt.Print("E-posta adresinizi giriniz: ") 18 |  fmt.Scan(&eposta) 19 |  if strings.Contains(eposta, "@") { 20 |   fmt.Println("E-posta Adresiniz Onaylandı!") 21 |  } else { 22 |   fmt.Println("Geçerli Bir E-posta Adresi Giriniz!") 23 |  } 24 | } 25 | ``` 26 | 27 | **”strings”** paketini eklemeyi unutmuyoruz. Bu kodlar ile kullanıcıdan e-posta adresi isteyen ve e-posta adresi içinde **@** işareti var ise olumlu yanıt veren bir programcık oluşturduk. **Constains()** fonksiyonunu açıklayacak olursak, **Contains** fonksiyonunun ilk parametresine kontrol edeceğimiz öğeyi giriyoruz. İkinci parametreye ise aranılacak **string** ifademizi giriyoruz. Gayet anlaşılır olduğunu düşünüyorum.\ 28 | **Strings.Count() Fonksiyonu**\ 29 | **Count()** fonksiyonu ile bir string değerin içinde istediğimiz bir string değerin kaç tane olduğunu öğrenebiliriz. Örneğimize geçelim. 30 | 31 | ```go 32 | package main 33 | import ( 34 |  "fmt" 35 |  "strings" 36 | ) 37 | func main() { 38 |  fmt.Println(strings.Count("deneme", "e")) 39 | } 40 | ``` 41 | 42 | **”strings”** paketini eklemeyi unutmuyoruz. Bu kodlar ile **Count()** fonksiyonunda **“deneme”** stringi içerisinde **“e”** stringinin kaç tane geçtiğini öğreniyoruz. Çıktımız **3** olacaktır.\ 43 | **Strings.Index() Fonksiyonu**\ 44 | **Index()** fonksiyonu ile bir **string** değerin içindeki istediğimiz bir string değerin kaçıncı sırada yani **index**’te olduğunu öğrenebiliriz.Sıra sıfırdan başlar. Örneğimize geçelim. 45 | 46 | ```go 47 | package main 48 | import ( 49 |  "fmt" 50 |  "strings" 51 | ) 52 | func main() { 53 |  fmt.Println(strings.Index("Merhaba Dünya", "h")) 54 | } 55 | ``` 56 | 57 | Çıktımız **h** harfi **0**’dan başlayarak 3. sırada olduğu için, **3** olacaktır.\ 58 | **Strings.LastIndex() Fonksiyonu**\ 59 | **LastIndex()** fonksiyonu ile bir **string** değerin içinde istediğimiz bir string değerin sırasını **Index()** fonksiyonunun tersine sağdan sola doğru kontrol eder. İlk çıkan sonucun index’ini seçer. Örnek: 60 | 61 | ```go 62 | fmt.Println(strings.LastIndex("Merhaba Dünya", "a")) 63 | ``` 64 | 65 | **”Merhaba Dünya”** yazısının içinde **“a”** harfini aradık. **LastIndex()** fonksiyonu sondan başa yani sağdan sola arama yaptığı için sondaki **“a”** harfini buldu. Yani **13** sonucunu ekrana bastırmış olduk.\ 66 | **Strings.Title() Fonksiyonu**\ 67 | **Title()** fonksiyonu ile içerisine küçük harflerle string türünde değer girdiğimizde baş harfleri büyük harf yapan bir fonksiyondur. 68 | 69 | ```go 70 | fmt.Println(strings.Title("merhaba dünya")) 71 | ``` 72 | 73 | Çıktımız **“Merhaba Dünya”** olacaktır.\ 74 | **Strings.ToUpper() Fonksiyonu**\ 75 | **ToUpper()** fonksiyonu içerisine girilen string değerin tüm harflerini büyük harf yapar. 76 | 77 | ```go 78 | fmt.Println(strings.ToUpper("merhaba dünya")) 79 | ``` 80 | 81 | Çıktımız **“MERHABA DÜNYA”** olacaktır.\ 82 | **Strings.ToLower() Fonksiyonu**\ 83 | **ToLower()** fonksiyonu içerisine girilen string değerin tüm harflerini küçük harf yapar. 84 | 85 | ```go 86 | fmt.Println(strings.ToLower("Merhaba Dünya")) 87 | ``` 88 | 89 | Çıktımız **“merhaba dünya”** olacaktır.\ 90 | **Strings.ToUpperSpecial() Fonksiyonu**\ 91 | **ToUpper()** fonksiyonu ile string değeri büyük harf yaptığımız zaman Türkçe karakter sıkıntısı yaşarız. Örnek olarak **“i”** harfi büyüyünce **“I”** harfi olur. Bunun önüne **ToUpperSpecial()** fonksiyonu ile geçebiliriz. Bu fonksiyonun ilk parametresine **karakter kodlamasını**, ikinci parametresine ise **string** değerimizi gireriz. Örnek olarak: 92 | 93 | ```go 94 | fmt.Println(strings.ToUpperSpecial(unicode.TurkishCase, "ıiüöç")) 95 | ``` 96 | 97 | Çıktımız **“IİÜÖÇ”** olacaktır.\ 98 | **Strings.ToLowerSpecial() Fonksiyonu**\ 99 | **ToUpperSpecial()** fonksiyonu ile aynı seçilde çalışır ;fakat harfleri belirlediğiniz karakter kodlamasına göre küçültür. Örnek kullanımı: 100 | 101 | ```go 102 | fmt.Println(strings.ToLowerSpecial(unicode.TurkishCase, "IİÜÖÇ")) 103 | ``` 104 | 105 | Çıktımız **“ıiüöç”** olacaktır. 106 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/bir-dizindeki-dosya-ve-klasoerleri-siralama.md: -------------------------------------------------------------------------------- 1 | # Bir Dizindeki Dosya ve Klasörleri Sıralama 2 | 3 | Golang üzerinde adresini belirlediğimiz bir dizindeki dosya ve klasörleri listelemeyi göreceğiz. Örneğimize geçelim: 4 | 5 | ```go 6 | package main 7 | import ( 8 | "fmt" 9 | "os" 10 | ) 11 | func diziniOku(d string) { 12 | dizin, err := os.Open(d) 13 | if err != nil { 14 | fmt.Println("Dizin bulunamadı!") 15 | os.Exit(1) 16 | } 17 | defer dizin.Close() 18 | liste, _ := dizin.Readdirnames(0) // Açıklamada okuyun 19 | for _, isim := range liste { 20 | fmt.Println(isim) 21 | } 22 | fmt.Printf("Toplamda %d içerik bulundu.\n", len(liste)) 23 | } 24 | func main() { 25 | diziniOku(".") 26 | } 27 | ``` 28 | 29 | Yukarıdaki kodlarımızın açıklamasını görelim:\ 30 | Öncelikle **“os”** paketimizi içe aktarıyoruz. **diziniOku()** fonksiyonumuzun içerisinde **dizin** adında değişken oluşturduk ve bu değişkende fonksiyonumuza **d** argümanı ile gelecek olan dizinimizi açtık. Eğer bir hata ile karşılaşırsak diye hata yakalama işlemini yaptık.\ 31 | Daha sonra **dizin** değişkenimizi **defer** ile kapattık.\ 32 | **liste** adında değişken oluşturduk. Bu değişkenimizin içerisine **dizin.Readdirnames(0)** diyerek tüm dosya ve klasörleri bu değişkenimizin içerisine attık. Burada sıfır kullanmamızın sebebi tüm dosya ve klasörleri okuyabilmek içindir.\ 33 | \ 34 | Hemen aşağısında **for** ve **range** ile **liste** değişkenimizdeki dosya ve klasör isimlerini isim değişkenimize bastırmak istedik. Her dosya ve klasör ayrı ayrı isim değişkenimize atandı ve ekrana bastırılmış oldu.\ 35 | \ 36 | Daha sonra **diziniOku()** fonksiyonumuzun en altında **len(liste)** ile dosya sayımızı öğrenerek ekrana bastırdık.\ 37 | \ 38 | **main()** fonksiyonumuzda ise **diziniOku(“.”)** diyerek nokta ile bulunduğumuz dizini okuttuk. 39 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/capraz-platform-dosya-yollari.md: -------------------------------------------------------------------------------- 1 | # Çapraz Platform Dosya Yolları 2 | 3 | Bir işletim sisteminde dosyanın veya dizinin yolunu belirtmek için taksim veya ters-taksim işaretleri kullanırız. Fakat yazağımız program çapraz-platformsa bu durumda ne yapmamız gerekir? 4 | 5 | Ya kendimiz bunun için bir fonksiyon oluşturacağız ya da kısa yoldan `os.PathSeperator`'ı kullanabiliriz. 6 | 7 | Hemen örneğimizi görelim: 8 | 9 | ```go 10 | package main 11 | 12 | import ( 13 | "fmt" 14 | "os" 15 | ) 16 | 17 | func main() { 18 | s := string(os.PathSeparator) 19 | yol := "dosyalar" + s + "muzikler" 20 | fmt.Println(yol) 21 | } 22 | ``` 23 | 24 | {% hint style="info" %} 25 | Her seferinde `string(os.PathSeperator)` yazmamak için `s` değişkenine atayarak kısalttık. 26 | {% endhint %} 27 | 28 | Windows için çıktımız: 29 | 30 | > dosyalar\muzikler 31 | 32 | Unix-Like için çıktımız: 33 | 34 | > dosyalar/muzikler 35 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/chromedp-web-driver.md: -------------------------------------------------------------------------------- 1 | # chromedp (Web Driver) 2 | 3 | **Chromedp** paketi, harici bağımlılıklar (Selenium veya PhantomJS gibi) olmadan Go'da **Chrome DevTools Protokolü**nü destekleyen tarayıcıları çalıştırmanın daha hızlı ve daha basit bir yoludur. Harici bağımlılık yoktur derken, tabi ki sisteminizde Google Chrome'un yüklü olması gerekiyor. Chromedp'ye headless modu gerektiği için minimum Chrome sürümünüz 59 olması gerekiyor. 4 | 5 | #### Paketi yüklemek için: 6 | 7 | > go get -u github.com/chromedp/chromedp 8 | 9 | ## Örnek.1 10 | 11 | ```go 12 | package main 13 | 14 | import ( 15 | "context" 16 | "log" 17 | 18 | "github.com/chromedp/chromedp" 19 | ) 20 | 21 | func main() { 22 | //chrome örneği oluşturalım 23 | ctx, cancel := chromedp.NewExecAllocator( 24 | context.Background(), 25 | append( 26 | chromedp.DefaultExecAllocatorOptions[:], 27 | chromedp.Flag("headless", false), 28 | )..., 29 | ) 30 | //headless: false ayarlayarak pencerenin görünmesini istedik 31 | 32 | //chrome nesnesini defer ile kapatmayı unutmuyoruz 33 | defer cancel() 34 | 35 | //yeni durum oluşturuyoruz 36 | ctx, cancel = chromedp.NewContext(ctx) 37 | 38 | //aynı şekilde defer ile penceremizide kapatıyoruz 39 | defer cancel() 40 | 41 | //Twitter isminin kaydedileceği değişkeni oluşturalım 42 | var twitterName string 43 | 44 | //chromedp.Run() içerisinde tarayıcıda yapılacak işlemleri yazıyoruz. 45 | err := chromedp.Run(ctx, //önce durumu (hangi pencere) olacağını belirtiyoruz 46 | 47 | //tarayıcının gitmsini istediğimiz adresi yazalım 48 | chromedp.Navigate(`https://kaanksc.com/posts/webview-statik-uygulama-ornegi3/`), 49 | 50 | //css seçici ile belirttiğimiz elementin yüklenmesini bekleyelim 51 | chromedp.WaitVisible(`.single__contents > p:nth-child(16) > a:nth-child(1)`, chromedp.ByQuery), 52 | 53 | //Tıklanılacak nesneyi yine css seçici ile belirtelim 54 | chromedp.Click(`.single__contents > p:nth-child(16) > a:nth-child(1)`, chromedp.ByQuery), 55 | //Bu işlemden sonra twitter'a gidecek 56 | 57 | //Twitter profilinde adın gösterildiği yeri css seçici ile beklemesini istedik 58 | chromedp.WaitVisible(`div.r-1b6yd1w:nth-child(1) > span:nth-child(1)`, chromedp.ByQuery), 59 | 60 | //belirttiğimiz css seçicisi ile elementin içindeki yazıyı twitterName değişkenine atayalım 61 | chromedp.Text(`div.r-1b6yd1w:nth-child(1) > span:nth-child(1)`, &twitterName), 62 | 63 | //burdan sonra tarayıcı penceresi kapanacak 64 | ) 65 | 66 | //hata kontrolü yapaım 67 | if err != nil { 68 | log.Fatal(err) 69 | } 70 | 71 | //son olarak twitterName içindeki değişkeni ekrana bastıralım 72 | log.Printf("Twitter İsim:%s\n", twitterName) 73 | } 74 | 75 | ``` 76 | 77 | Yukarıdaki örnekte yeni chrome penceresi oluşturma, tıklama, elementin yüklenmesini bekleme, element içindeki yazıyı alma ve adrese gitme gibi işlemlerin nasıl yapıldığını gördük. 78 | 79 | ## Örnek.2 80 | 81 | Go Playground linkinden Go kodlarını çeken bir uygulama yazalım. 82 | 83 | ```go 84 | package main 85 | 86 | import ( 87 | "context" 88 | "log" 89 | 90 | "github.com/chromedp/chromedp" 91 | ) 92 | 93 | func main() { 94 | //chrome örneği oluşturalım 95 | ctx, cancel := chromedp.NewExecAllocator( 96 | context.Background(), 97 | append( 98 | chromedp.DefaultExecAllocatorOptions[:], 99 | chromedp.Flag("headless", true), //Bu sefer headless çalışmasını istedik 100 | //yani chrome pecneresi açılmayacak 101 | )..., 102 | ) 103 | 104 | //chrome nesnesini defer ile kapatmayı unutmuyoruz 105 | defer cancel() 106 | 107 | //yeni durum oluşturuyoruz 108 | ctx, cancel = chromedp.NewContext(ctx) 109 | 110 | //aynı şekilde defer ile penceremizide kapatıyoruz 111 | defer cancel() 112 | 113 | //go Kodlarının kaydedileceği değişkeni oluşturalım 114 | var goKodu string 115 | 116 | //chromedp.Run() içerisinde tarayıcıda yapılacak işlemleri yazıyoruz. 117 | err := chromedp.Run(ctx, //önce durumu (hangi pencere) olacağını belirtiyoruz 118 | 119 | //tarayıcının gitmsini istediğimiz adresi yazalım 120 | chromedp.Navigate(`https://play.golang.org/p/a_SoTzENmV7`), 121 | 122 | //tarayıcının yüklenemesini bekleyeceği elementi css seçici ile yazıyoruz 123 | chromedp.WaitVisible(`#code`, chromedp.ByQuery), 124 | 125 | //textContent ile yazı alanı içeriğini çekebiliriz. 126 | chromedp.TextContent(`#code`, &goKodu, chromedp.ByQuery), 127 | ) 128 | 129 | if err != nil { 130 | log.Fatal(err) 131 | } 132 | 133 | //son oalrak go kodlarını ekrana bastıralım 134 | log.Printf("Go Kodu:\n%s", goKodu) 135 | } 136 | 137 | ``` 138 | 139 | Yukarıdaki örnekte headless modda çalışmayı ve yazı kutusu (input veya textarea) içindeki yazıları almayı öğrendik. 140 | 141 | Daha fazla bilgi için [https://github.com/chromedp/chromedp](https://github.com/chromedp/chromedp), 142 | 143 | daha fazla örnek için [https://github.com/chromedp/examples](https://github.com/chromedp/examples) adresine bakabilirsiniz. 144 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/dosya-varligi-kontrolue.md: -------------------------------------------------------------------------------- 1 | # Dosya Varlığı Kontrolü 2 | 3 | Go programımızda kullancağımız bir bir dosyanın varlığını `os` paketi ile kontrol edebiliriz. Örnek programımızı görelim: 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "os" 11 | ) 12 | 13 | func main() { 14 | if d := "dosya.txt"; dosyaVarmı(d) { 15 | fmt.Println(d, "bulunuyor") 16 | } else { 17 | fmt.Println(d, "bulunmuyor!") 18 | } 19 | } 20 | 21 | func dosyaVarmı(isim string) bool { 22 | bilgi, hata := os.Stat(isim) 23 | if os.IsNotExist(hata) { 24 | return false 25 | } 26 | return !bilgi.IsDir() 27 | } 28 | ``` 29 | 30 | **Gelelim açıklmasına:** 31 | 32 | Dosya işlemleri yapabilmek için `os` paketini import ettik. if-else akışında geçici değişken olarak `d` değişkenine `"dosya.txt"` atayarak kontrol edilecek dosyamızın ismini belirledik. 33 | 34 | Bu akışta `dosyaVarmı` fonksiyonunda `true` değer dönerse `dosya.txt bulunuyor` olarak çıktı almamız gerekir. 35 | 36 | `dosyaVarmı` fonksiyonunu incelediğimizde `bilgi` ve `hata` değişkenlerine `os.Stat` ile dosyanın bilgilerini çektik. `hata` değişkeni `false` döndürürse fonksiyonun `false` döndürmesini istedik. Aynı şekilde `bilgi.IsDir()` ile dosya değil de bir dizinse `false` döndürmesini istedik. 37 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/ini-dosyasi-okuma-ve-duezenleme.md: -------------------------------------------------------------------------------- 1 | # ini Dosyası Okuma ve Düzenleme 2 | 3 | ini dosyaları programımızın ayarlarını barındırabileceğimiz dosyalardır. Golang’de ini dosyalarını paket ekleyerek yapabiliriz. Paketimizi indirmek için aşağıdaki komutu yazıyoruz. 4 | 5 | > go get gopkg.in/ini.v1 6 | 7 | Paketimizi indirdikten sonra ini dosyamız üzerinde işlemler yapabiliriz.\ 8 | Aşağıdaki örneklerde kullanacağımız ini dosyası bu şekildedir. Dosyamızın ismi **ayarlar.ini** olsun. 9 | 10 | ``` 11 | # Yorum satırımız 12 | uygulama_modu = geliştirme 13 | [dizinler] 14 | veri = ./dosyalar 15 | [sunucu] 16 | protokol = http 17 | port = 8000 18 | ``` 19 | 20 | **Ini Dosyası Okuma** 21 | 22 | Dosya okuma işlemimiz dizin mantığında çalışır. Örneğimizi görelim. 23 | 24 | ```go 25 | package main 26 | import ( 27 | "fmt" 28 | "gopkg.in/ini.v1" 29 | ) 30 | func kontrol(e error) { 31 | if e != nil { 32 | panic(e) 33 | } 34 | } 35 | func main() { 36 | veri, err := ini.Load("ayarlar.ini") 37 | kontrol(err) 38 | fmt.Println("Uygulama Modu:", veri.Section("").Key("uygulama_modu").String()) 39 | fmt.Println("Veri Dizini:", veri.Section("dizinler").Key("veri").String()) 40 | fmt.Println("Bağlantı Protokolü:", veri.Section("sunucu").Key("protokol").String()) 41 | fmt.Println("Bağlantı Portu:", veri.Section("sunucu").Key("port").MustInt(9999)) 42 | } 43 | ``` 44 | 45 | Çıktımız şu şekilde olacaktır. 46 | 47 | > Uygulama Modu: geliştirme\ 48 | > Veri Dizini: ./dosyalar\ 49 | > Bağlantı Protokolü: http\ 50 | > Bağlantı Portu: 8000 51 | 52 | 53 | 54 | **Inı Dosyası Düzenleme** 55 | 56 | Yine aynı **ayarlar.ini** dosyası üzerinde düzenlemeler yapalım. İşte örneğimiz: 57 | 58 | ```go 59 | package main 60 | import ( 61 | "gopkg.in/ini.v1" 62 | ) 63 | func kontrol(e error) { 64 | if e != nil { 65 | panic(e) 66 | } 67 | } 68 | func main() { 69 | veri, err := ini.Load("ayarlar.ini") 70 | kontrol(err) 71 | // Değer atıyoruz. 72 | veri.Section("").Key("uygulama_modu").SetValue("ürün") 73 | // ini dosyamızı kaydetmeyi unutmuyoruz. 74 | veri.SaveTo("ayarlar.ini") 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/ioutil-ile-dosya-okuma-ve-yazma.md: -------------------------------------------------------------------------------- 1 | # ioutil ile Dosya Okuma ve Yazma 2 | 3 | **ioutil** paketi standart Golang paketleri içerisinde gelir ve dosya işlemleri yapabilmemiz için bize fonksiyonlar sağlar. 4 | 5 | **Dosya Okuma** 6 | 7 | Hemen örneğimize geçelim. Açıklamaları kod üzerinde ilgili alanlara yazdım. 8 | 9 | ```go 10 | package main 11 | import ( 12 | "fmt" 13 | "io/ioutil" 14 | ) 15 | // Hatayı kontrol etmek için fonksiyonumuz 16 | func kontrol(err error) { 17 | if err != nil { 18 | panic(err) 19 | } 20 | } 21 | func main() { 22 | // Okunacak dosyamızı belirtiyoruz 23 | dosya, err := ioutil.ReadFile("dosya.txt") 24 | // Hata kontrolü yapıyoruz. 25 | kontrol(err) 26 | //Dosyamızın içeriğini ekrana bastırıyoruz. 27 | fmt.Println(string(dosya)) 28 | } 29 | ``` 30 | 31 | {% hint style="info" %} 32 | Okuma işlemi **byte** tipinde yapıldığı için **string()** fonksiyonu ile byte tipini string tipine dönüştürüyoruz. 33 | {% endhint %} 34 | 35 | **Dosya Yazma** 36 | 37 | ```go 38 | package main 39 | import ( 40 | "io/ioutil" 41 | ) 42 | // Hatayı kontrol etmek için fonksiyonumuz 43 | func kontrol(err error) { 44 | if err != nil { 45 | panic(err) 46 | } 47 | } 48 | func main() { 49 | // Yazmak istediğimiz veriyi belirtiyoruz 50 | veri := []byte("golangtr.org") 51 | // Dosya yazma işlemini başlatıyoruz. 52 | err := ioutil.WriteFile("dosya.txt", veri, 0644) // 0644 dosya yazdırma izni oluyor. 53 | // Hata kontrolü yapıyoruz. 54 | kontrol(err) 55 | } 56 | ``` 57 | 58 | {% hint style="info" %} 59 | String tipini dosyaya yazdırmamız için önce byte tipine çevirmemiz gerekir. 60 | {% endhint %} 61 | 62 | Dosya yazdırma işleminde aynı isimde dosya varsa üzerine yazar. 63 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/isletim-sistemini-goerme.md: -------------------------------------------------------------------------------- 1 | # İşletim Sistemini Görme 2 | 3 | Go programının çalıştığı işletim sistemi görmek için aşağıdaki kodları yazabilirsiniz. 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "runtime" 11 | ) 12 | 13 | func main() { 14 | 15 | if r := runtime.GOOS; r == "windows" { 16 | fmt.Println("Windows için yönetici olarak çalıştırın.") 17 | } else if r == "linux" { 18 | fmt.Println("Linux için sudo komutu ile çalıştırın.") 19 | } else { 20 | fmt.Println("Geçersiz işletim sistemi!") 21 | } 22 | } 23 | ``` 24 | 25 | GNU/Linux kullandığım için çıktım aşağıdaki gibi olacaktır. 26 | 27 | > Linux için sudo komutu ile çalıştırın. 28 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/web-scrapper.md: -------------------------------------------------------------------------------- 1 | # Web Scrapper (goquery) 2 | 3 | Bu yazıda Go dilinde nasıl basitçe web scrapper yapacağımıza bakacağız. 4 | 5 | ### Web Scrapper Nedir? 6 | 7 | Web Scrapper bir web sayfasındaki elementleri işleyen araçtır. 8 | 9 | **Örnek uygulama:** 10 | 11 | **blog.golang.org** sitesindeki blog başlıklarını listeleyen Go programının yazılması. 12 | 13 | ```go 14 | package main 15 | 16 | import ( 17 | "fmt" 18 | "log" 19 | "net/http" 20 | 21 | "github.com/PuerkitoBio/goquery" 22 | ) 23 | 24 | func main() { 25 | blogBasliklari, err := baslikCek("https://blog.golang.org") 26 | if err != nil { 27 | log.Println(err) 28 | } 29 | fmt.Println("Başlıklar:") 30 | fmt.Printf(blogBasliklari) 31 | } 32 | 33 | // URL adresinden blog başlıklarını çekecek fonksiyon 34 | func baslikCek(url string) (string, error) { 35 | 36 | // HTML'i çek 37 | resp, err := http.Get(url) 38 | if err != nil { 39 | return "", err 40 | } 41 | 42 | // goquery dökümanına çevir 43 | doc, err := goquery.NewDocumentFromReader(resp.Body) 44 | if err != nil { 45 | return "", err 46 | } 47 | 48 | // liste oluştur 49 | basliklar := "" 50 | doc.Find(".title a").Each(func(i int, s *goquery.Selection) { 51 | basliklar += "- " + s.Text() + "\n" 52 | }) 53 | return basliklar, nil 54 | } 55 | 56 | ``` 57 | 58 | Açıklaması:\ 59 | goquery kütüphanesini bilgisayarımıza indiriyoruz. 60 | 61 | > go get github.com/PuerkitoBio/goquery 62 | 63 | `baslikCek` fonksiyonuna URL adresini girdik. Zaten bu fonksiyonu da bi oluşturduk. Hata kontrolü yaptıktan sonra başlıkları yazdırdık. 64 | 65 | `baslikCek` fonksiyonuna baktığımızda;\ 66 | İlk önce url adresini, yani içindeki elementleri, çektik. goquery dökümanına çevirdik. Burada dikkat edilmesi gereken nokta, `resp` değişkeni bizim çektiğimiz url adresidir. Daha sonra liste olarak oluşturduk. Liste oluşturma işleminde `.title` sınıfına ait ve `a` etiketinde olan elementleri sıralamasını istedik. Element seçim işlemi jQuery selector mantığında çalışır. 67 | 68 | Çıktımız: 69 | 70 | {% hint style="info" %} 71 | Başlıklar: 72 | 73 | * Announcing the 2019 Go Developer Survey 74 | * Go.dev: a new hub for Go developers 75 | * Go Turns 10 76 | * Go Modules: v2 and Beyond 77 | * Working with Errors in Go 1.13 78 | {% endhint %} 79 | -------------------------------------------------------------------------------- /boeluem-7-dosya-islemleri/xml-parsing-ayristirma.md: -------------------------------------------------------------------------------- 1 | # XML Parsing (Ayrıştırma) 2 | 3 | Bu yazımıza Golang üzerinde **XML** dosyalarını işlemeyi öğreneceğiz. Bu işlemin yapabileceğimiz hali hazırda standart Golang paketleri ile gelen **“encoding/xml”** paketi vardır. Örneğimize geçelim.\ 4 | **veri.xml** isminde aşağıdaki gibi bir belgemiz olduğunu varsayalım. 5 | 6 | ```markup 7 | 8 | <üyeler> 9 | <üye tip="admin"> 10 | Ahmet 11 | 12 | https://facebook.com 13 | https://twitter.com 14 | https://youtube.com 15 | 16 | 17 | <üye tip="okuyucu"> 18 | Mehmet 19 | 20 | https://facebook.com 21 | https://twitter.com 22 | https://youtube.com 23 | 24 | 25 | 26 | ``` 27 | 28 | **XML Belgemizi Okuyalım** 29 | 30 | Bu işlemimizi yaparken **“io/ioutil”** ve **“os”** paketlerimizden faydalanacağız. Hemen kodlarımızı görelim. 31 | 32 | ```go 33 | package main 34 | import ( 35 | "fmt" 36 | "os" 37 | ) 38 | func main() { 39 | // XML dosyamızı açıyoruz 40 | xmlDosya, err := os.Open("veri.xml") 41 | // Hata var mı diye kontrol ediyoruz 42 | if err != nil { 43 | fmt.Println(err) 44 | } 45 | fmt.Println("veri.xml dosyası başarıyla açıldı") 46 | // XML dosyamızı kapatmayı unutmuyoruz. 47 | defer xmlDosya.Close() 48 | } 49 | ``` 50 | 51 | Eğer XML dosyası açılırken hata oluşmazsa çıktımız olumlu yönde olacaktır.\ 52 | Şimde XML dosyasındaki verileri struct’ımıza kaydedelim. Parsing işlemi de yapacağımızdan dolayı **“encoding/xml”** paketini de içe aktarıyoruz. Hemen kodumuz geliyor. 53 | 54 | ```go 55 | package main 56 | import ( 57 | "encoding/xml" 58 | "fmt" 59 | "io/ioutil" 60 | "os" 61 | ) 62 | type Üyeler struct { 63 | Alan xml.Name `xml:"üyeler"` 64 | Üyeler []Üye `xml:"üye"` 65 | } 66 | type Üye struct { 67 | Alan xml.Name `xml:"üye"` 68 | Tip string `xml:"tip,attr"` 69 | İsim string `xml:"isim"` 70 | Sosyal Sosyal `xml:"sosyal"` 71 | } 72 | type Sosyal struct { 73 | Alan xml.Name `xml:"sosyal"` 74 | Facebook string `xml:"facebook"` 75 | Twitter string `xml:"twitter"` 76 | Youtube string `xml:"youtube"` 77 | } 78 | func main() { 79 | // XML dosyamızı açıyoruz 80 | xmlDosya, err := os.Open("veri.xml") 81 | // Hata var mı diye kontrol ediyoruz 82 | if err != nil { 83 | fmt.Println(err) 84 | } 85 | // XML dosyamızı kapatmayı unutmuyoruz. 86 | defer xmlDosya.Close() 87 | //XML dosyamızı okuyoruz (byte olarak geliyor) 88 | byteDeğer, _ := ioutil.ReadAll(xmlDosya) 89 | //Yerleştirme işlemi için değişken oluşturuyoruz. 90 | var üyeler Üyeler 91 | xml.Unmarshal(byteDeğer, &üyeler) 92 | fmt.Println(üyeler.Üyeler) 93 | } 94 | ``` 95 | -------------------------------------------------------------------------------- /go-programlama-dili.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/go-programlama-dili.epub -------------------------------------------------------------------------------- /golangtrlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/golangtrlogo.png -------------------------------------------------------------------------------- /gopher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/gopher.png -------------------------------------------------------------------------------- /goprogramlamadiliv1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/goprogramlamadiliv1.pdf -------------------------------------------------------------------------------- /goprogramlamadiliv2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/goprogramlamadiliv2.pdf -------------------------------------------------------------------------------- /goprogramlamadiliv3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/goprogramlamadiliv3.pdf -------------------------------------------------------------------------------- /goprogramlamadiliv4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/goprogramlamadiliv4.pdf -------------------------------------------------------------------------------- /gui/notify-bildirim.md: -------------------------------------------------------------------------------- 1 | # notify (Bildirim) 2 | 3 | Bazen programımızda kullanıcının haberdar olması için bildirim özelliği gerekir. Bu özelliği `notify` paketi ile kazandırabiliriz. 4 | 5 | > go get github.com/martinlindhe/notify 6 | 7 | Paketi indirdikten sonra, aşağıdaki kodları deneyebilirsiniz. 8 | 9 | ```go 10 | package main 11 | 12 | import "github.com/martinlindhe/notify" 13 | 14 | func main() { 15 | // Bildirim Gösterme 16 | notify.Notify("Uygulama İsmi", "Başlık", "Açıklama", "icon/yolu.png") 17 | 18 | // Sesli Bilgirim Gösterme 19 | notify.Alert("Uygulama İsmi", "Başlık", "Açıklama", "icon/yolu.png") 20 | } 21 | ``` 22 | 23 | ![GNU/Linux (Ubuntu'da)](../.gitbook/assets/linux.png) 24 | 25 | ![macOS / OSX 10.8+](<../.gitbook/assets/macos (1).png>) 26 | 27 | ![Windows 10](<../.gitbook/assets/windows (1).png>) 28 | -------------------------------------------------------------------------------- /kapaktanitim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ksckaan1/go-programlama-dili/a95e6339273735f9147c6412b79b7fb1d6462a71/kapaktanitim.png -------------------------------------------------------------------------------- /kitap-hakkinda/katkida-bulunanlar.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Değerli vaktini ayırıp, dökümanın geliştirilmesine katkıda bulunan kişiler 3 | --- 4 | 5 | # Katkıda Bulunanlar 6 | 7 | \*Liste harf sıralamasına göre yapılmıştır. 8 | 9 | | PP | Kişi | Github | 10 | | ----------------------------------------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------- | 11 | | | Adem Ali Durmuş | [@ademalidurmus](https://github.com/ademalidurmus) | 12 | | | Adem İlter | [@ademilter](https://github.com/ademilter) | 13 | | | Aykut Kardaş | [@aykutkardas](https://github.com/aykutkardas) | 14 | | | Berkay Çoban | [@berkaycoban](https://github.com/berkaycoban) | 15 | | | Emre Önal | [@emmreonal](https://github.com/emmreonal) | 16 | | | Erhan Yakut | [@yakuter](https://github.com/yakuter) | 17 | | | Hazarek | [@hazerek](https://github.com/hazarek) | 18 | | | Latif Uluman | [@latif70427517](https://twitter.com/latif70427517) | 19 | | | Mert Şimşek | [@mertingen](https://github.com/mertingen) | 20 | | | Murat Mirgün Ercan | [@muratmirgun](https://github.com/muratmirgun) | 21 | | | Yunus Emre Geldegül | [@emregeldegul](https://github.com/emregeldegul) | 22 | | | Yusuf Dündar | [@yusufdundar](https://github.com/yusufdundar) | 23 | | | Yusuf Turhan Papurcu | [@yusufpapurcu](https://github.com/yusufpapurcu) | 24 | -------------------------------------------------------------------------------- /mikro-denetleyiciler/gobot-ile-arduino-yanip-soenen-led-yapimi.md: -------------------------------------------------------------------------------- 1 | # Gobot ile Arduino Yanıp-Sönen LED Yapımı 2 | 3 | Bu yazımda sizlere Golang için Robotik kütüphanesi olan **Gobot**‘tan bir örnek göstereceğim. Bu örneğimizde Arduino’da yanıp sönen LED yapacağız.\ 4 | İlk olarak Gobot kütüphanesini indiriyoruz. 5 | 6 | > go get -d -u gobot.io/x/gobot/... 7 | 8 | Daha sonra Arduino’muzla iletişim kurabilmemiz için **Gort**‘u yüklememiz gerekiyor.\ 9 | [https://gort.io/documentation/getting\_started/downloads/](https://gort.io/documentation/getting\_started/downloads/)\ 10 | Bu örnekte **Arduino Uno** kullanacağız. Arduino’muzun bilgisayarımıza bağlıyoruz ve hangi porta bağlı olduğunu öğrenmek için komut satırına aşağıdakileri yazıyoruz. 11 | 12 | > gort scan serial 13 | 14 | Windows’ta **\** benzeri, Linux’ta ise **/dev/ttyUSB\*** benzeri bir çıktı verecektir. Bu bizim Arduino’muzun bağlı olduğu portu gösteriyor.\ 15 | Aşağıdaki kodlar yanıp sönen LED için yazılmıştır. Kodları gördükten sonra açıklamasını yapacağım. 16 | 17 | ```go 18 | package main 19 | import ( 20 | "time" 21 | "gobot.io/x/gobot" 22 | "gobot.io/x/gobot/drivers/gpio" 23 | "gobot.io/x/gobot/platforms/firmata" 24 | ) 25 | func main() { 26 | firmataAdaptor := firmata.NewAdaptor("/dev/ttyUSB0") 27 | led := gpio.NewLedDriver(firmataAdaptor, "13") 28 | work := func() { 29 | gobot.Every(2*time.Second, func() { 30 | led.Toggle() 31 | }) 32 | } 33 | robot := gobot.NewRobot("bot", 34 | []gobot.Connection{firmataAdaptor}, 35 | []gobot.Device{led}, 36 | work, 37 | ) 38 | robot.Start() 39 | } 40 | ``` 41 | 42 | Açıklamasına gelirsek;\ 43 | Gobot ile alakalı kütüphanelerimizi ekliyoruz. **firmataAdaptor** değişkenimizde Arduino’muzun portunu yazıyoruz. Ben Linux kullandığım için Linux’taki portunu yazdım. **led** değişkenimizde ledimizin **13**. dijital pinde yer aldığını belirttik. Yani LED’imizin artı ucunu **13. pine** eksi ucunu ise **GND** (Ground-Toprak-Nötr) girişine bağlayacağız. 44 | 45 | Sıra geldi çalışma fonksiyonumuz olan **work**‘e. **work** değişkenine anonim bir fonksiyon tanımladık. Bu fonksiyonda **led.Toggle()** fonksiyonu ile her **2** saniyede yanıp-sönmesini ayarladık. En sondaki **robot** değişkeninde ise firmataAdaptor değişkenimizdeki Arduino portuyla bağlantı kurmasını ve hemen altında **led** değişkenini cihaz olarak tanıttık. Son olarak **work** değişkenindeki olayları gerçekleştirip, **robot.Start()** fonksiyonu ile çalışmasını sağladık.\ 46 | Yukarıda gördüğünüz üzere **Firmata** kelimesini kullandık. Firmata bizim Arduino cihazımız ile iletişimde bulunabilmemizi sağlayan bir yazılım. Yukarıdaki kodlarımızın çalışması için Arduino’muz içerisine Firmata yazılımını yüklememiz gerekir. Onu da yüklemesi aşağıdaki gibi çok kolay bir işlem. 47 | 48 | > gort arduino upload firmata /dev/ttyUSB0 49 | 50 | **/dev/ttyUSB0** yerine kendi Arduino portunuzu yazmayı unutmayın.\ 51 | Uygulamamızı başlatmak için ise aşağıdakileri yazıyoruz. 52 | 53 | > go run main.go 54 | 55 | **main.go** yerine ne isim verdiyseniz onu yazınız. 56 | -------------------------------------------------------------------------------- /mikro-denetleyiciler/tinygo-ile-kuecuek-yerler-icin-golang.md: -------------------------------------------------------------------------------- 1 | # Tinygo ile Küçük Yerler için Golang 2 | 3 | ![Tinygo Logosu](../.gitbook/assets/tinygo-logo.png) 4 | 5 | Tinygo, Golang kodları ile mikro-denetleyicilere program yazmamızı sağlayan bir derleyicidir. 6 | 7 | Aynı zamanda yazdığımız kodları mikro-denetleyicinin beynine flash eder. Flash etme kelimesinden kastım, beyne çalışacak kodları yazdırmaktır. 8 | 9 | {% content-ref url="gobot-ile-arduino-yanip-soenen-led-yapimi.md" %} 10 | [gobot-ile-arduino-yanip-soenen-led-yapimi.md](gobot-ile-arduino-yanip-soenen-led-yapimi.md) 11 | {% endcontent-ref %} 12 | 13 | Gobot ile Arduino Yanıp-Sönen LED Yapımı konusunda bahsettiğim. Gobot paketinden farkı, Gobot Firmata yazılımını Arduino’ya gömdükten sonra Arduino’ya çalıştırılabilir komutlar yolluyor. Yani kodlarımızı Arduino içine gömmediğinden, sadece Arduino USB veya TCP ile bağlı olduğundan çalışıyor. 14 | 15 | Fakat Tinygo, Golang kodlarımızı Arduino’nun içerisine gömüyor. Bu sebeble Arduino’nun kodlarımızı çalıştırması için sadece bir elektrik kaynağına bağlı olması yetiyor. 16 | 17 | **Gelelim Kuruluma** 18 | 19 | ### GNU/Linux 20 | 21 | Ubuntu/DebianBirinci Adım:\ 22 | `wget https://github.com/tinygo-org/tinygo/releases/download/v0.9.0/tinygo_0.9.0_amd64.deb`\ 23 | İkinci Adım:\ 24 | `sudo dpkg -i tinygo_0.9.0_amd64.deb`\ 25 | Üçüncü Adım:\ 26 | `export PATH=$PATH:/usr/local/tinygo/bin`RaspBerry PiBirinci Adım:\ 27 | `wget https://github.com/tinygo-org/tinygo/releases/download/v0.9.0/tinygo_0.9.0_armhf.deb`\ 28 | İkinci Adım:\ 29 | `sudo dpkg -i tinygo_0.9.0_armhf.deb`\ 30 | Üçüncü Adım:\ 31 | `export PATH=$PATH:/usr/local/tinygo/bin`Arch LinuxAUR deposundan [tinygo-bin](https://aur.archlinux.org/packages/tinygo-bin/) olarak aratabilirsiniz.Fedora Linux`sudo dnf install tinygo` 32 | 33 | ### **Windows** 34 | 35 | Öncelikle şuanda Windows üzerinde deneme aşamasında olduğunu söylemeliyim. 36 | 37 | İlk olarak LLVM 8’i kurmalısınız. 38 | 39 | [Buradan indirme sayfasına gidebilirsiniz.](http://releases.llvm.org/download.html#8.0.1) 40 | 41 | LLVM 8 kurulumu esnasında “LLVM’yi ortam değişkenlerine ekle” seçeneğini seçmeyi unutmayın. 42 | 43 | Daha sonra Tinygo arşiv dosyasını indirelim. 44 | 45 | [Tinygo Arşiv Dosyası İndir](https://github.com/tinygo-org/tinygo/releases/download/v0.9.0/tinygo0.9.0.windows-amd64.zip) 46 | 47 | Aşağıdaki komut ile Tinygo’yu kuralım. 48 | 49 | `PowerShell Expand-Archive -Path "c:\Downloads\tinygo0.9.0.windows-amd64.zip" -DestinationPath "c:\tinygo"` 50 | 51 | Aşağıdaki komut ile Tinygo’yu ortam değişkenlerine ekleyelim. 52 | 53 | `set PATH=%PATH%;C:\tinygo\bin;` 54 | 55 | ### MacOS 56 | 57 | İlk adım: 58 | 59 | ​`brew tap tinygo-org/tools` 60 | 61 | İkinci Adım: 62 | 63 | `brew install tinygo` 64 | 65 | ### Kurulum Sonrası 66 | 67 | Kurulum işlemlerimiz tamamlandıktan sonra kontrol etme amaçlı komut satırına aşağıdaki komutları yazalım. 68 | 69 | `tinygo version` 70 | 71 | Kullandığınız işletim sistemine göre fark göstermekle birlikte aşapıdakine benzer bir çıktı alacaksınız. 72 | 73 | `tinygo version 0.9.0 linux/amd64 (using go version go1.12.9)` 74 | 75 | Bu işlemler sırasında elimde bulunan Arduino Uno kartı ile işlemler yapacağımız belirteyim. Diğer kartlar ile arasında çok bir işlem farkı bulunmamaktadır. Aynı veya benzer yollardan sizce bu işlemleri gerçekleştirebilirsiniz. 76 | 77 | Öncelikle Arduino Uno kartımızın hangi USB portuna bağlı olduğunu bulalım. 78 | 79 | Windows üzerinden **COM3** benzeri bir portta takılıdır. İnternet üzerinden detaylı araştırma yapabilirsiniz. 80 | 81 | Unix-like sistemlerde (Linux, MacOS) ise genelde **/dev/ttyUSB** veya **/dev/ttyACM** portarından birinde takılı olabilir. Arduino’nun bağlı olduğu portu `ls /dev/ttyUSB*` komutu ile öğrenebilirsiniz. 82 | 83 | Ben Arduino Uno kartımın **/dev/ttyUSB0** üzerinde olduğu için aşağıdaki işlemlerimi ona göre yapacağım. Kullandığım komutları kendi portunuza göre değiştirmeyi unutmayın. 84 | 85 | Aşağıda Arduino UNO üzerindeki Built-In LED’i saniyede bir yanıp-söndürmeye yarayan Golang kodları yer alıyor. 86 | 87 | ```go 88 | package main 89 | 90 | import ( 91 | "machine" 92 | "time" 93 | ) 94 | 95 | func main() { 96 | led := machine.LED 97 | led.Configure(machine.PinConfig{Mode: machine.PinOutput}) 98 | for { 99 | led.Low() 100 | time.Sleep(time.Millisecond * 1000) 101 | 102 | led.High() 103 | time.Sleep(time.Millisecond * 1000) 104 | } 105 | } 106 | ``` 107 | 108 | Dosyamızın ismini main.go yapalım. Yukarıdaki Golang kodlarımızı kaydettikten sonra komut satırını main.go dosyasının bir üst klasöründe açalım. 109 | 110 | Go kodlarımızı Arduino üzerine yazdırmak için aşağıdaki komutları kullanalım. 111 | 112 | `tinygo flash -target=arduino -port=/dev/ttyUSB0 ./kodumuzunbulunduğuklasör` 113 | 114 | Gördüğünüz gibi Tinygo ile flash etme işlemi çok basit. 115 | -------------------------------------------------------------------------------- /pratik-bilgiler/derleme-build-detayini-goerme.md: -------------------------------------------------------------------------------- 1 | # Derleme (Build) Detayını Görme 2 | 3 | Golang’de normalde derleme işlemini yapmak için go build komutunu kullanırız. Bu komut terminal ekranından bize sadece bir hata olduğunda bilgi verir. Hata yoksa çalıştırılabilir dosyayı zaten oluşturur.\ 4 | 5 | 6 | **Peki programımızın derlenme esnasında bilgilendirmeyi nasıl görebiliriz?** 7 | 8 | İşte aşağıdaki gibi: 9 | 10 | > go build -gcflags=-m main.go 11 | 12 | Yani build’e ek parametre olarak **-gcflags=-m** yazıyoruz. Nasıl gözüktüğünü örnek olarak görelim. 13 | 14 | ```go 15 | package main 16 | import ( 17 | "fmt" 18 | "os" 19 | ) 20 | func main() { 21 | fmt.Println("Merhaba") 22 | fmt.Println(topla(2,2)) 23 | os.Exit(0) 24 | } 25 | func topla(x,y int) int{ 26 | return x + y 27 | } 28 | ``` 29 | 30 | Yukarıdaki kodumuzun derleme çıktısı şöyle olacaktır. 31 | 32 | > command-line-arguments\ 33 | > ./main.go:13:6: can inline topla\ 34 | > ./main.go:9:13: inlining call to fmt.Println\ 35 | > ./main.go:10:22: inlining call to topla\ 36 | > ./main.go:10:16: inlining call to fmt.Println\ 37 | > ./main.go:9:14: "Merhaba" escapes to heap\ 38 | > ./main.go:9:13: io.Writer(os.Stdout) escapes to heap\ 39 | > ./main.go:10:16: io.Writer(os.Stdout) escapes to heap\ 40 | > ./main.go:10:22: topla(2, 2) escapes to heap\ 41 | > ./main.go:9:13: main \[]interface {} literal does not escape\ 42 | > ./main.go:10:16: main \[]interface {} literal does not escape\ 43 | > :1: os.(\*File).close .this does not escape 44 | -------------------------------------------------------------------------------- /pratik-bilgiler/dinamik-degiskenler.md: -------------------------------------------------------------------------------- 1 | # Dinamik Değişkenler 2 | 3 | Daha önceki bölümlerden de gördüğümüz üzere Go, dinamik atamayı desteklemiyor. Ama bunun elbette bir yöntemi var. Bunun için `interface`'den faydalanabiliriz. 4 | 5 | Örnek: 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | ) 13 | 14 | //dinamik atama yapabilmek için önce boş bir interface oluşturalım 15 | type dynamic interface{} 16 | 17 | func main() { 18 | 19 | //x değişkenimizin tipini interface olarak belirleyelim 20 | var x dynamic 21 | 22 | //x'e integer tipinde değer atayalım 23 | x = 13 24 | 25 | //x'in tipini ve değerini ekrana bastıralım 26 | fmt.Printf("%T:%v\n", x, x) //int:13 27 | 28 | //Daha sonradan x'e string tipinde değer atayalım 29 | x = "selam" 30 | 31 | //x'in tipini ve değerini ekrana bastıralım. 32 | fmt.Printf("%T:%q\n", x, x) //string:"selam" 33 | } 34 | ``` 35 | 36 | Yukarıdaki örnekte görüldüğü üzere `x` değişkenimize hangi tipte atama yaparsak, `x` değerin tipine dönüşüyor. 37 | 38 | ### Any 39 | 40 | Go'ya gelen güncellemeden sonra `interface{}` yazmak yerine `any` yazarsanız aynı işlemi görür. 41 | 42 | ```go 43 | var degisken any 44 | ``` 45 | -------------------------------------------------------------------------------- /pratik-bilgiler/go-gelistiricileri-icin-makefile.md: -------------------------------------------------------------------------------- 1 | # Go Geliştiricileri için Makefile 2 | 3 | Golang ile yazılım geliştirirken **Makefile** teknolojisinde nasıl faydalanacağımızı göreceğiz. Gözümüzün korkmasına gerek yok, aşırı basit bir olay. Zaten herşeyi biliyorsunuz. Makefile sadece bir yöntemdir.\ 4 | 5 | 6 | **Makefile Nedir?** 7 | 8 | **Makefile**, çoğu komutu çalıştırmak için kullanabileceğimiz otomasyon aracıdır. Makefile’ı genellikle Github veya Gitlab’de programların ana dizininde bazı işlemleri otomatikleştirme için kullanıldığını görebilirsiniz.\ 9 | 10 | 11 | **Basit Bir Örnek** 12 | 13 | Bir proje klasörü oluşturalım ve bu klasörün içine **makefile** adında dosya oluşturalım. Daha sonra makefile dosyamızı herhangi bir editör ile açalım ve içerisine aşağıdakileri yazalım. 14 | 15 | ```python 16 | merhaba: 17 | echo "merhaba" 18 | ``` 19 | 20 | Gördüğünüz gibi programlama dillerine ve komutlara benzer bir yazılımı var.\ 21 | Kodumuzu **make** komutu ile deneyebiliriz. Proje klasörümüzün içerisinde komut satırına **make merhaba** yazarak kodumuzun çıktısını görelim: 22 | 23 | > echo "Merhaba"\ 24 | > Merhaba 25 | 26 | Gördüğünüz gibi **make** komutunun yanına **merhaba** ekleyerek **makefile** dosyamızdaki merhaba bölümünün çalışmasını sağladık. Makefile’ın genel mantığına baktığımızda komut satırı üzerinden yaptığımız işlemleri kısaltıyor.\ 27 | 28 | 29 | **Basit Go Uygulaması İnşa Etme** 30 | 31 | ```go 32 | package main 33 | import "fmt" 34 | func main() { 35 | fmt.Println("Merhaba") 36 | } 37 | ``` 38 | 39 | Yukarıda gördüğünüz gibi basit bir Go uygulamamız var. Şimdi bu Go dosyamız ile işlem yapabilmek için **makefile** dosyamıza komutlar girelim. 40 | 41 | ```python 42 | merhaba: 43 | echo "Merhaba" 44 | build: 45 | go build main.go 46 | run: 47 | go run main.go 48 | ``` 49 | 50 | Yukarıda gördüğünüz gibi **makefile** dosyamıza bloklar açarak bildiğiniz komut satırı komutlarını girdik. Yukarıdaki kodların durumuna göre **make build** ile Go dosyamızı build ederiz ve **make run** ile Go dosyamızı çalıştırırız. Gayet basit bir mantığı var. 51 | 52 | **Peki bu olay bizim ne işimize yarayacak?** 53 | 54 | Örneğin bir projeyi 3 tane platform için build etmemiz gerekecek. Her platform için ayrı Go Ortamı bilgisi girmemiz gerekir. Hele ki build işlemini sürekli yapıyorsanız bu işten bıkabilirsiniz. Fakat makefile dosyasıyla işinizi kolaylaştırabilirsiniz.\ 55 | Örneğimizi görelim: 56 | 57 | ```python 58 | derle: 59 | echo "Windows, Linux ve MacOS için Derleme İşlemi" 60 | GOOS=windows GOARCH=amd64 go build -o bin/main-windows64.exe main.go 61 | GOOS=linux GOARCH=amd64 go build -o bin/main-linux64 main.go 62 | GOOS=darwin GOARCH=amd64 go build -o bin/main-macos64 main.go 63 | run: 64 | go run main.go 65 | hepsi: derle run 66 | ``` 67 | 68 | **derle** bloğumuzun içerisine 3 platforma derlemek için komutlarımızı girdik. **run** bloğuna ise **main.go** dosyamızı çalıştırmak için komutumuzu girdik. **hepsi** bloğunun yanına ise **derle** ve **run** yazdık. Yani komut satırına **make hepsi** yazarsak hem derleme hem de çalıştırma işlemini yapacak.\ 69 | \ 70 | Bu yazımızda **Golang için** **makefile** kullanımına örnek verdik. İlla ki Go’da kullanılacak diye bir kaide yok. Diğer programlama dillerinde veya komutlarınızı otomatize etmek istediğiniz zaman kullanabilirsiniz. 71 | -------------------------------------------------------------------------------- /pratik-bilgiler/isletim-sistemini-goerme.md: -------------------------------------------------------------------------------- 1 | # İşletim Sistemini Görme 2 | 3 | Go programının çalıştığı işletim sistemi görmek için aşağıdaki kodları yazabilirsiniz. 4 | 5 | ```go 6 | package main 7 | 8 | import ( 9 | "fmt" 10 | "runtime" 11 | ) 12 | 13 | func main() { 14 | 15 | if r := runtime.GOOS; r == "windows" { 16 | fmt.Println("Windows için yönerici olarak çalıştırın.") 17 | } else if r == "linux" { 18 | fmt.Println("Linux için sudo komutu ile çalıştırın.") 19 | } else { 20 | fmt.Println("Geçersiz işletim sistemi!") 21 | } 22 | } 23 | ``` 24 | 25 | GNU/Linux kullandığım için çıktım aşağıdaki gibi olacaktır. 26 | 27 | > Linux için sudo komutu ile çalıştırın. 28 | 29 | -------------------------------------------------------------------------------- /pratik-bilgiler/visual-studio-code-icin-golang-oezellestirmeleri.md: -------------------------------------------------------------------------------- 1 | # Visual Studio Code için Golang Özelleştirmeleri 2 | 3 | Bu yazıda Visual Studio Code üzerinde Golang için kullanabileceğimiz özelleştirmelerden bahsedeceğiz. Bu özelleştirmeler sayeseinde kod yazma deneyimimizi iyileştirebiliriz. 4 | 5 | ## Canlı Hata Ayıklama 6 | 7 | VSCode üzerinde Go dili kodları yazarken farketmişsinizdir. Kodu yazarken hata ayıklamıyor. Sadece dosyayı kaydettiğimizde hata ayıklama işlemi yapıyor. Kod üzerinde canlı hata ayıklamayı aktif etmemiz gerekiyor. Bunun için; 8 | 9 | `CTRL + SHIFT + P` tuşlarına beraber basarak, VSCode komut bölümünü açalım. Bu kısma `"Preferences: Open User Settings"` yazalım ve çıkan ilk sonuca girelim. 10 | 11 | ![Adım.1](../.gitbook/assets/prefer.png) 12 | 13 | Açılan `Settings` sekmesinde üst tarafta bulunan arama yapma kutusuna `"Go: Live Errors"` yazalım. Çıkan sonuçta `"Edit in settings.json"` bağlantısına tıklayalım. 14 | 15 | ![Adım.2](../.gitbook/assets/prefer2.png) 16 | 17 | ```javascript 18 | "go.liveErrors": { 19 | "enabled": false, //Burayı true yapalım. 20 | "delay": 500 //tepki süresi 21 | } 22 | ``` 23 | 24 | Açılan editörde `"go.liveErrors"` anahtarının karşısında ayarlarımız var. `"enabled"` anahtarının değerini `true` yapalım. `"delay"` anahtarındaki değerde ise yazdıktan kaç milisaniye sonra hata ayıklama yapacağını belirtiyoruz. `500` (yarım saniye) normal bir değerdir. 25 | 26 | Daha sonra bir `.go` dosyası oluşturalım veya hali hazırda `.go` dosyasını açalım. Açtığımız dosyanın içerisine birşeyler yazmaya çalıştığımızda VSCode'un sağ alt köşesinde bir uyarı verecektir. Bu uyarıda **Install** butonuna tıklayarak eklenti yükleme işlemini başlatalım. Bu eklenti canlı hata ayıklama yapmak için gereklidir. Yüklendiğinde **Output** sekmesinde aşağıdakine benzer bir sonuç alacaksınız. 27 | 28 | > Tools environment: GOPATH=C:\Users\kaank\go Installing 1 tool at C:\Users\kaank\go\bin in module mode. gotype-live\ 29 | > \ 30 | > Installing github.com/tylerb/gotype-live (C:\Users\kaank\go\bin\gotype-live.exe) SUCCEEDED\ 31 | > \ 32 | > All tools successfully installed. You are ready to Go :). 33 | 34 | Artık canlı hata ayıklama özelliğini kullanabilirsiniz. 35 | 36 | ![Canlı Hata Ayıklama](../.gitbook/assets/livedebug.gif) 37 | 38 | ## Go Yazarken Kullanabileceğiniz VSCode Eklentileri 39 | 40 | ### ErrorLens 41 | 42 | Bu eklenti ile kod yazarken eğer hata varsa alakalı satırın sağında hata mesajını görebilirsiniz. Bu eklentiyi Go için kullanmadan önce Go için canlı hata ayıklamayı açmanızı tavsiye ederim _(Yukarıda gösterdim)_. 43 | 44 | ![ErrorLens Eklentisi](../.gitbook/assets/errorlens.png) 45 | 46 | ### Better Comments 47 | 48 | Yorum satırlarını daha şık gösteren bir eklentidir. Tavsiye ederim. Satırın başına koyduğunuz işaret veya yazdığınız yazıya göre satırın rengi değişiyor. 49 | 50 | ![Better Comments Eklentisi](../.gitbook/assets/bc.png) 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /veritabani/gorm.md: -------------------------------------------------------------------------------- 1 | # GORM 2 | 3 | **Gorm** kütüphanesi sql kullanımını kolaylaştıran ve az kod ile çok iş yapabileceğiniz bir kütüphanedir. **Gorm** kütüphanesini yüklemek için komut satırına aşağıdakileri yazın. 4 | 5 | ``` 6 | go get -u gorm.io/gorm 7 | ``` 8 | 9 | #### Gorm Özellikleri 10 | 11 | * Tam Özellikli ORM 12 | * Hooks (oluşturma/kaydetme/güncelleme/silme/bulmadan önce/sonra) 13 | * Preload, Joins ile istekli yükleme 14 | * İşlemler, İç İçe İşlemler, Kaydetme Noktası, Kaydedilen Noktaya Geri Dönme 15 | * Bağlam, Hazırlanan İfade Modu, DryRun Modu 16 | * Toplu Ekleme, FindInBatches, Map ile Bul/Oluştur, SQL Expr ve Context Valuer ile CRUD 17 | * SQL Builder, Upsert, Locking, Optimizer/Index/Comment İpuçları, Adlandırılmış Bağımsız Değişken, Alt Sorgu 18 | * Bileşik Birincil Anahtar, Dizinler, Kısıtlamalar 19 | * Otomatik Taşıma 20 | * Genişletilebilir, esnek eklenti API: Database Resolver (birden çok veritabanı, okuma/yazma bölme) / Prometheus… 21 | * Geliştirici Dostu 22 | 23 | Gorm kütüphanesini kullanabilmemiz için bir sql dili seçmemiz gerekmektedir. Bu öğreticide sqlite kullanacağız. Sqlite kütüphanesini yüklemek için komut satırına aşağıdakileri yazın. 24 | 25 | ``` 26 | go get -u gorm.io/driver/sqlite 27 | ``` 28 | 29 | ### **Gorm Kütüphanesinin Kullanımı** 30 | 31 | `main.go` dosyamızı oluşturalım. Kütüphanelerimizi import edelim. 32 | 33 | {% code title="main.go" %} 34 | ```go 35 | import ( 36 | "fmt" 37 | "gorm.io/driver/sqlite" 38 | "gorm.io/gorm" 39 | ) 40 | ``` 41 | {% endcode %} 42 | 43 | `"gorm.io/gorm"` kütüphanesi ile gorm fonksiyonlarına erişiyoruz. Gorm ile sqlite entegrasyonunu sağlamak için ise "gorm.io/driver/sqlite" kütüphanesini kullanıyoruz bu kütüphane kullandığını sql diline göre değişiklik göstermektedir. Şimdi basit şekilde veri tabanı bağlantısı ve crud işlemleri nasıl yapılır görelim. 44 | 45 | Gorm da manuel olarak tablo oluşturmanız gorm işleyişine tersdir. Bunun yerine bir struct oluşturacağız ve struct içerisine deki özelliklere göre gorm otomatik tablo oluşturacaktır. Struct otomatik tablo çıktı almak için struct içerisinde en üste `gorm.Model` eklentisini eklememiz gerekmektedir. 46 | 47 | ```go 48 | type User struct { 49 | gorm.Model 50 | Username string `gorm:"not null;size:30"` 51 | } 52 | ``` 53 | 54 | `sqlite` **'a** bağlanmak için bizden bir veritabanı adı istiyor bu veritabanını kendi otomatik oluşturacaktır; 55 | 56 | ```go 57 | db, _ := gorm.Open(sqlite.Open("data.db"), &gorm.Config{}) 58 | ``` 59 | 60 | Oluşturmuş olduğumuz struct ile `AutoMigrate()` fonksiyonunu kullanarak tablo oluşturalım. `Create()` fonksiyonu ile oluşturulan tablomuzun içerisine bir `name` ekleyelim. 61 | 62 | {% code title="main.go" %} 63 | ```go 64 | func main() { 65 | db, _ := gorm.Open(sqlite.Open("veri.db"), &gorm.Config{}) 66 | defer db.Close() 67 | db.AutoMigrate(&User{}) // Tablo oluşturma 68 | 69 | db.Create(&User{Username: "eren"}) // Tablo içerisine insert 70 | } 71 | ``` 72 | {% endcode %} 73 | 74 | Sqlite tablomuz aşağıdaki şekilde gözükmelidir. Gorm otomatik olarak oluşturma, güncelleme ve silinme tarihlerini belirten sütunlar eklemektedir. 75 | 76 |

Tablo görünümü

77 | 78 | Tablomuza bir veri daha ekleyelim tablo içerisinde **id** ile arama yapabilmek için `First()` fonksiyonunu kullanacağız sonucu terminalden alalım. 79 | 80 | ``` 81 | func main() { 82 | db, _ := gorm.Open(sqlite.Open("veri.db"), &gorm.Config{}) 83 | defer db.Close() 84 | db.AutoMigrate(&User{}) // oluşturma 85 | 86 | db.Create(&User{Username: "furkan"}) //ekleme 87 | 88 | var users User 89 | db.First(&users, 2) // id 2 olan kullanıcı getirilecektir. 90 | fmt.Println(users) 91 | } 92 | ``` 93 | -------------------------------------------------------------------------------- /veritabani/mongodb.md: -------------------------------------------------------------------------------- 1 | --- 2 | description: Twitter @YusihCano 3 | --- 4 | 5 | # MongoDB 6 | 7 | **MongoDB** 2009 yılında geliştirilmiş açık kaynak kodlu bir NoSQL veritabanıdır. Şimdi Go ile MongoDB veritabanını kullanmak için `mongo-driver` paketini indirelim. 8 | 9 | > go get go.mongodb.org/mongo-driver/mongo 10 | 11 | Kodu sürekli tekrardan yapıştırmamak için import edilecek tüm kütüphaneler burada : 12 | 13 | ```go 14 | package main 15 | 16 | import ( 17 | "context" 18 | "log" 19 | "time" 20 | 21 | "go.mongodb.org/mongo-driver/bson" 22 | "go.mongodb.org/mongo-driver/bson/primitive" 23 | "go.mongodb.org/mongo-driver/mongo" 24 | "go.mongodb.org/mongo-driver/mongo/options" 25 | ) 26 | ``` 27 | 28 | Şimdi de `database` ile bağlantıyı sağlayalım. Eğer database adresini bilmiyorsanız mongo konsolunuzun nereye bağlandığına bakarak database adresini bulabilirsiniz. 29 | 30 | ```go 31 | databaseURL := "mongodb://127.0.0.1:27017" 32 | ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) 33 | client, err := mongo.Connect(ctx, options.Client().ApplyURI(databaseURL)) 34 | if err != nil { 35 | log.Fatal("Hata : " + err.Error()) 36 | } 37 | kisiler := client.Database("test").Collection("kisiler") 38 | ``` 39 | 40 | Bu kısım `main` fonksiyonununun başlangıcı. Kısaca yapılan ise ilk satırda database adresini verdik. Ardından 10 saniye timeout'u olan bir context açtık. Context ve database adresini kullanarak bağlantımızı gerçekleştirdik.Son satırda da istedigimiz veritabanı ve collection'u çektik. Bundan sonra isim adında bir struct oluşturalım. Kişinin ismini ve yaşını tutsun. 41 | 42 | ```go 43 | type Kisi struct { 44 | ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` 45 | Isim string `bson:"isim,omitempty" json:"isim,omitempty"` 46 | Yas int `bson:"yas,omitempty"json:"yas,omitempty"` 47 | } 48 | ``` 49 | 50 | Şimdi de bir kişi oluşturup database'e ekleyelim. 51 | 52 | ```go 53 | birisi := Kisi{ 54 | Isim: "Ahmet", 55 | Yas: 42, 56 | } 57 | res, err := kisiler.InsertOne(context.TODO(), birisi) 58 | if err != nil { 59 | log.Fatal("Hata : " + err.Error()) 60 | } 61 | 62 | id := res.InsertedID 63 | fmt.Println(id) 64 | ``` 65 | 66 | Kişi oluşturma ve ekleme işlemlerinden sonra eklenen verinin id'sini de yazdırdık. MongoDB Compass ya da konsol üzerinden `db.kisiler.find()` yaparak eklenen veriyi görebiliriz. Şimdi de veri okuma yapalım. Tüm verileri almak için : 67 | 68 | ```go 69 | ctx, _ = context.WithTimeout(context.Background(), 30*time.Second) 70 | cur, err := kisiler.Find(ctx, bson.D{}) 71 | if err != nil { 72 | log.Fatal("Hata : " + err.Error()) 73 | } 74 | defer cur.Close(ctx) 75 | var list []Kisi 76 | for cur.Next(ctx) { 77 | var result Kisi 78 | err := cur.Decode(&result) 79 | if err != nil { 80 | log.Fatal("Hata : " + err.Error()) 81 | } 82 | list = append(list, result) 83 | } 84 | if err := cur.Err(); err != nil { 85 | log.Fatal("Hata : " + err.Error()) 86 | } 87 | fmt.Println(list) 88 | ``` 89 | 90 | Şimdi de her hangi bir özelliğe göre arama yapalım. 91 | 92 | ```go 93 | var result Kisi 94 | ctx, _ = context.WithTimeout(context.Background(), 5*time.Second) 95 | err = kisiler.FindOne(ctx, bson.M{"yas": 42}).Decode(&result) 96 | if err != nil { 97 | log.Fatal("Hata : " + err.Error()) 98 | } 99 | out, err := json.Marshal(&result) 100 | if err != nil { 101 | log.Fatal("Hata : " + err.Error()) 102 | } 103 | fmt.Println(string(out)) 104 | ``` 105 | 106 | Silme işlemi yapalım. 107 | 108 | ```go 109 | ctx, _ = context.WithTimeout(context.Background(), 5*time.Second) // Context for Delete 110 | _, err = kisiler.DeleteOne(ctx, bson.D{{"yas", 39}}) // Delete User 111 | if err != nil { 112 | log.Fatal("Hata : " + err.Error()) 113 | } 114 | ``` 115 | 116 | İsterseniz başka bir değer üzerinden de silme işlemi yapabilirsiniz. Ben direk istenen veriyi silmek için id kullanmanızı tavsiye ediyorum. Şimdi de Update ile temel fonksiyonları bitirelim. 117 | 118 | ```go 119 | degisecek := Kisi{ 120 | Isim: "Kemal", 121 | Yas: 39, 122 | } 123 | yeni := Kisi{ 124 | Isim: "Kemal", 125 | Yas: 100, 126 | } 127 | var filtre bson.M 128 | bytes, err := bson.Marshal(degisecek) 129 | if err != nil { 130 | log.Fatal("Hata : " + err.Error()) 131 | } 132 | bson.Unmarshal(bytes, &filtre) 133 | var usr bson.M 134 | bytes, err = bson.Marshal(yeni) 135 | if err != nil { 136 | log.Fatal("Hata : " + err.Error()) 137 | } 138 | bson.Unmarshal(bytes, &usr) 139 | update := bson.D{ 140 | {"$set", usr}, 141 | } 142 | ctx, _ = context.WithTimeout(context.Background(), 5*time.Second) 143 | _, err = kisiler.UpdateOne(ctx, filtre, update) 144 | if err != nil { 145 | log.Fatal("Hata : " + err.Error()) 146 | } 147 | ``` 148 | -------------------------------------------------------------------------------- /web-sunucu-server-ag-istemleri/gin-web-kuetuephanesi/gin-dosya-yuekleme.md: -------------------------------------------------------------------------------- 1 | # Gin Dosya Yükleme 2 | 3 | Bu yazıda Gin kütüphanesinden `POST` isteği ile nasıl dosya yükleyeceğimizi göreceğiz. 4 | 5 | Aşağıda projemizin dizin/dosya yapısı bulunuyor. 6 | 7 | ``` 8 | . 9 | ├── main.go 10 | └── public 11 | └── index.html 12 | ``` 13 | 14 | İlk olarak `index.html` dosyamızı görelim. 15 | 16 | ```markup 17 | 18 | 19 | 20 | 21 | 22 | Dosya Yükle 23 | 24 | 25 | 26 |

Yüklemek için 1 adet dosya seçin

27 | 28 |
29 | İsim:
30 | E-posta:
31 | Dosya:

32 | 33 |
34 | 35 | ``` 36 | 37 | Detaylıca değinmiyorum. `input` elementlerinin `name` özelliğinde ne isim verdiğimizi dikkat etmemiz yeterli. `form` elementinin action özelliğine `/yukle` adresini verdik. 38 | 39 | `main.go` dosyamız ise aşağıdaki gibi olacaktır. Detaylarına yorum satırlarında değindim. 40 | 41 | ```go 42 | package main 43 | 44 | import ( 45 | "fmt" 46 | "path/filepath" 47 | 48 | "github.com/gin-gonic/gin" 49 | ) 50 | 51 | func main() { 52 | 53 | router := gin.Default() 54 | //Yükleme yapacağımız dosyanın maksimum boyutunu 55 | //ayarlayalım. 56 | router.MaxMultipartMemory = 8 << 20 // 8 MiB 57 | 58 | //index.html dosyamızın bulunduğu klasörü static olarak 59 | //ekliyoruz ki index.html dosyamızı kullanabilelim. 60 | router.Static("/", "./website") 61 | 62 | //yukleme işlemini yapacak olduğumuz yönlendirmeyi 63 | //buradan ayarlıyoruz. 64 | router.POST("/yukle", func(c *gin.Context) { 65 | 66 | //form içerisindeki dosya hariç verilerimizi 67 | //atayalım 68 | isim := c.PostForm("isim") 69 | eposta := c.PostForm("email") 70 | 71 | // Dosyamızı ise özel fonksiyon ile atıyoruz 72 | dosya, hata := c.FormFile("dosya") 73 | 74 | //Hata kontrolü yapmayı unutmayalım. 75 | if hata != nil { 76 | c.String(400, fmt.Sprintf("Form Hatası: %s", hata.Error())) 77 | return 78 | } 79 | 80 | //yüklenecek olan dosyanın ismini alalım. 81 | dosyaismi := filepath.Base(dosya.Filename) 82 | 83 | //yüklenen dosyanın kaydedileceği konum 84 | // dizin + dosyaismi 85 | kayıtYeri := "./website/" + dosyaismi 86 | 87 | //dosyayı kaydedelim ve hata kontrolü yapalım. 88 | if hata := c.SaveUploadedFile(dosya, kayıtYeri); hata != nil { 89 | c.String(400, fmt.Sprintf("Dosya Yükleme Hatası: %s", hata.Error())) 90 | return 91 | } 92 | 93 | //Şuana kadar herhangi bir sıkıntı ile 94 | //karşılaşmadıysak, olumlu mesajımızı gösterelim. 95 | c.String(200, fmt.Sprintf("%s isimli dosya başarıyla yüklendi \nİsim: %s\nE-posta: %s", dosya.Filename, isim, eposta)) 96 | }) 97 | router.Run(":8080") 98 | } 99 | ``` 100 | -------------------------------------------------------------------------------- /web-sunucu-server-ag-istemleri/net-http-ile-web-server-olusturma.md: -------------------------------------------------------------------------------- 1 | # net/http ile Web Server Oluşturma 2 | 3 | Golang’ta web sunucusu oluşturma çok basit bir işlemdir.\ 4 | İlk örneğimizde **localhost:5555** üzerinde çalışacak olan bir web sunucusu oluşturacağız. 5 | 6 | ```go 7 | package main 8 | import ( 9 | "fmt" 10 | "net/http" 11 | ) 12 | 13 | func handler(w http.ResponseWriter, r *http.Request) { 14 | fmt.Fprintf(w, "Merhaba %s", r.URL.Path[1:]) 15 | } 16 | 17 | func main() { 18 | http.HandleFunc("/", handler) 19 | http.ListenAndServe(":5555", nil) 20 | 21 | fmt.Println("Web Sunucu") 22 | } 23 | ``` 24 | 25 | Tarayıcınız üzerinden **localhost:5555**‘e girdiğinizde sayfada sadece **Merhaba** yazdığını göreceksiniz. Daha sonra adrese **/ahmet** yazıp girdiğiniz zaman yazının **Merhaba ahmet** olarak değiştiğini göreceksiniz.\ 26 | 27 | 28 | **Peki bu olayın açıklaması nedir?**\ 29 | **main()** fonksiyonunun içerisinde 2 temel fonksiyon bulunuyor. **HandleFunc()** fonksiyonu belirlediğimiz adrese girildiğinde hangi fonksiyonun çalıştırılacağınız belirliyor. **ListenAndServe()** fonksiyonu ise sunucunun ayağa kalkmasını ve istediğimiz bir porttan ulaşılmasını sağlıyor.\ 30 | Eğer sunucuya dosya verme yoluyla işlem yapmasını istiyorsak aşağıdaki yönteme başvurmalıyız.\ 31 | **index.html** adında bir dosya oluşturuyoruz. İçine aşağıdakileri yazıyoruz ve kaydediyoruz. 32 | 33 | ```markup 34 | 35 | 36 | 37 | Sayfa Başlığı 38 | 39 | 40 | Merhaba Dünya 41 | 42 | 43 | ``` 44 | 45 | Şimde de sunucu işlemlerini gerçekleştireceğimiz **main.go** dosyamızı oluşturalım. 46 | 47 | ```go 48 | package main 49 | import ( 50 | "fmt" 51 | "io/ioutil" 52 | "net/http" 53 | ) 54 | 55 | func loadFile(fileName string) (string, error) { 56 | bytes, err := ioutil.ReadFile(fileName) 57 | if err != nil { 58 | return "", err 59 | } 60 | return string(bytes), nil 61 | } 62 | 63 | func handler(w http.ResponseWriter, r *http.Request) { 64 | var body, _ = loadFile("index.html") 65 | fmt.Fprintf(w, body) 66 | } 67 | 68 | func main() { 69 | http.HandleFunc("/", handler) 70 | http.ListenAndServe(":5555", nil) 71 | } 72 | ``` 73 | 74 | Tarayıcıdan **localhost:5555** adresine girdiğimiz zaman oluşturmuş olduğumuz **index.html** dosyasının görüntülendiğini göreceksiniz.\ 75 | Açıklayacak olursak eğer;\ 76 | **loadFile()** fonksiyonumuz **index.html** programa aktarıldığında **byte** türünde olduğu için onu okuyabileceğimiz **string** türüne çevirdi. Bu özellik programımıza **“io/ioutil”** paketi sayesinde eklendi. Geri kalan kısımdan zaten yukarıda bahsetmiştik. 77 | -------------------------------------------------------------------------------- /web-sunucu-server-ag-istemleri/rabbitmq/README.md: -------------------------------------------------------------------------------- 1 | # RabbitMQ 2 | 3 | {% hint style="info" %} 4 | RabbitMQ hakkında bilginiz varsa sonraki sayfaya geçebilirsiniz. 5 | {% endhint %} 6 | 7 | ## RabbitMQ Nedir? 8 | 9 | Öncelikle RabbitMQ hakkında bilgi edinmek veya bilgilerini tazelemek isteyenler için ufak bir bilgi edinelim. 10 | 11 | RabbitMQ, mesaj kuyruğu sistemidir. AMQP üzerinde kurulu bir sistemdir. 12 | 13 | ### Peki AMQP Nedir? 14 | 15 | AMQP'nin açılımı Advenced Message Queue Protocol'dür (Gelişmiş Mesaj Kuyruğu Sistemi). 16 | 17 | Basitçe kabul edilen mesajları sıraya göre işleyebileceğimiz bir protokoldür. 18 | 19 | 20 | 21 | ### Peki biz bu sistemi hangi ihtiyaçlarımızı gidermek için kullanırız? 22 | 23 | Bizim için önemli olan kısım burası. En çok kullanılan alanlar, 24 | 25 | * Uzun süren işlemler ve arkaplan işlemleri, 26 | * Mikroservisler arasındaki iletişim (aracılık), 27 | * Basitçe dosya işleme (ve alt kategorilerde), 28 | * Arkaplan sistem ölçekleme ve yedeklemedir. 29 | 30 | Yukarıdaki maddelerin daha anlaşılır olması için ufak bir senaryo düşünelim. 31 | 32 | Bir sunucumuz var ve bu sunucumuz bir parametre alarak, bu parametre hakkında belirli mecralardan veri topluyor. Fakat bu veri toplama işi, sistemi yorabilecek bir işlem. Bu parametremizi sistemimizi kullanan kullanıcıdan aldığımızı düşünelim. 33 | 34 | #### Peki aynı anda birden fazla kullanıcıdan parametre alıp veri araştırması yaptığımız bir durum ile karşılaşırsak ne olurdu? 35 | 36 | Belirli bir işlemden sonra sunucumuzun bulunduğu sistemin kaynakları yetersiz gelirdi ve tabiri caizse sunucumuz çökerdi. 37 | 38 | İşte böyle bir örnek durumda Message Queue kullanabiliriz. 39 | 40 | ## RabbitMQ Çalışma Akışı 41 | 42 | ![](../../.gitbook/assets/workflow-rabbitmq.png) 43 | 44 | Yukarıdaki şemada, basitçe bir Message Queue'nin hangi işlemlerden geçtiğini görebiliriz. 45 | 46 | Kavramlara göz atmak gerekirse; 47 | 48 | #### Producer 49 | 50 | Producer, mesajımızı RabbitMQ'ya gönderen arkadaşımız. Mesajımız düz bir yazı haricinde bir yapı da (json vs...) olabilir. Bu olayda mesaj diye adlandırılır. Producer basitçe bir yayınlayıcıdır ve RabbitMQ'ya mesajımızı gönderir. 51 | 52 | #### Broker 53 | 54 | Broker, Producer'dan gelen mesajları sıraya alır ve mesajı almaya müsait olan bir Consumer'a gönderir. Yani mesajlarımızı depolayan bir birimdir. 55 | 56 | #### Consumer 57 | 58 | Comsumer ise broker'a gelen mesajları alır ve istenilen şekilde mesajlar ile işlemler yapabilir. Ve hatta aldığı mesajlara bir yanıt üretebilir (rpc olarak kullanıldığında). 59 | 60 | 61 | 62 | #### Bahsettiğimiz senaryoya RabbitMQ'yu entegre etseydik, senaryomuz şöyle sonuçlanırdı. 63 | 64 | Örnek olarak kullanıcıdan isim soyisim aldığımızı düşünelim ve bu aldığımızı bilgiyi internette aratarak bilgi toplayacağımızı düşünelim. İşlemimiz uzun sürebileceği için böyle bir işlemi hızlı olmasını istediğimiz bir sunucuda yapmak istemeyebiliriz. Bunun için isim-soyisim'i Broker'ımız olan RabbitMQ'ya mesaj olarak atıyoruz ve bu mesajlarımızı teker teker consumer, yani asıl araştırma yükünü üstlenecek kısım alıp mesaj içeriğine göre araştırma yapacak. Toplanılan bilgiyi bir veritabanına kaydedecek veya istenirse mesajı gönderen producer'a cevap olarak dönebilecek. 65 | 66 | Eğer cevap olarak dönerse producer'ımız araştırma işlemi bitene kadar bekleyecek fakat sistemimiz birden fazla araştırma yaparak yorulmamış olarak. 67 | 68 | İstersek birden fazla consumer oluşturarak aynı anda birden fazla isim-soyisim araştırması da yapabiliriz. Bu biraz da kurduğumuz sisteme bağlı bir işlem. 69 | 70 | Ufak ufak örnekler ile konumuzu pekiştirebiliriz. 71 | -------------------------------------------------------------------------------- /web-sunucu-server-ag-istemleri/rabbitmq/rabbitmq-kurulumu.md: -------------------------------------------------------------------------------- 1 | # RabbitMQ Kurulumu 2 | 3 | Herşeyden önce bize bir RabbitMQ sunucusu lazım. Bunun için [bu adresten](https://www.rabbitmq.com/#getstarted) RabbitMQ'yu indirebilirsiniz. 4 | 5 | İsterseniz benim de sıkça kullanıdığım gibi bir Heroku hesabınız var ise RabbitMQ'yu ücretsiz olarak eklenti olarak kullanabiliriz. 6 | 7 | Sunucumuzu ayağa kaldırmak için aşağıdaki komutu kullanalım. 8 | 9 | ``` 10 | rabbitmq-server 11 | ``` 12 | 13 | `Starting broker... completed with 7 plugins.` mesajını görürsek başarılı bir şekilde çalışıtığını görebiliriz. 14 | 15 | RabbitMQ sunucumuzu yerel makinamızda ayağa kaldırdıysak varsayılan olarak aşağıdaki bilgiler ile erişilebilir olacaktır. 16 | 17 | `amqp://guest:guest@localhost:5672/` 18 | -------------------------------------------------------------------------------- /web-sunucu-server-ag-istemleri/statik-kuetuephanesi-ile-dosyalari-uygulamaya-goemme.md: -------------------------------------------------------------------------------- 1 | # Statik Kütüphanesi ile Dosyaları Uygulamaya Gömme 2 | 3 | Golang’ın müthiş yanlarından biri de bir uygulamayı build ettiğimizde bize tek çalıştırılabilir dosya şeklinde sunmasıdır. Fakat bu özellik sadece **.go** dosyalarını birleştirilmesinde kullanılıyor. Harici dosyalar programa gömülmüyor. Fakat **Statik** isimli kütüphane ile bu işlem mümkün kılınıyor.\ 4 | Kütüphanenin mantığından kısaca bahsedeyim. Belirlediğiniz bir dizindeki dosyaları bir kodlamaya çevirerek programın içine dosya gömmek yerine kod gömüyor. Ve bu kodu sanki dosyaymışcasına kullanabiliyoruz. Tabi ki sadece sunucu işlemlerinde işe yarar olduğunu belirtelim.\ 5 | Bu yöntemin güzel artı yönleri var. 6 | 7 | * Programımız tek dosya halinde kalıyor. 8 | * Programımız kapalı kaynak oluyor. 9 | 10 | Tanıtımını yaptığımıza göre hafiften uygulamaya başlayalım. 11 | 12 | > go get github.com/rakyll/statik 13 | 14 | Konsola yukarıdakini yazarak kütüphanemizi indiriyoruz. Öncelikle dosya ve klasör yapımızı aşağıdaki gibi ayarlıyoruz. 15 | 16 | ![Proje klasörümüzün dizin düzeni](../.gitbook/assets/statik.png) 17 | 18 | Kodlamaya dönüştürülmesini istediğimiz klasör ile işlem yapıyoruz. Yani **public** klasörü ile. Aşağıdaki komutu **Proje klasörümüz** içerisindeyken yazıyoruz. 19 | 20 | > statik -src=/public/klasörünün/adresi -f 21 | 22 | Bu işlemle birlikte **public** klasörümüzün yanına statik isimli bir klasör oluşturduk ve içine **statik.go** isimli dosya oluşturmuş olduk. Bu dosyanın içerisinde bizim **public** klasörümüzün kodlanmış hali mevcuttur.\ 23 | Ve sırada **main.go** dosyamızı oluşturmakta. Aşağıdaki kodlarıda **main.go** dosyamıza yazıyoruz. 24 | 25 | ```go 26 | package main 27 | import ( 28 | "net/http" 29 | "github.com/rakyll/statik/fs" 30 | _ "./statik" //Oluşturulmuş statik.go dosyasının konumu 31 | ) 32 | func main() { 33 | statikFS, _ := fs.New() 34 | http.Handle("/", http.StripPrefix("/", http.FileServer(statikFS))) 35 | http.ListenAndServe(":5555", nil) 36 | } 37 | ``` 38 | 39 | Gerekli kütüphanelerimizi ekledikten sonra **main()** fonksiyomuzun içeriğini inceleyelim. 40 | 41 | **statikFS** ve **\_** adında değişkenlerimizi tanımladık. Bu değişkenlerimizi fonksiyonel değişkendir. **\_** koymamızın sebebi **error** çıktısını kullanmak istemediğimizdendir. Eğer lazım olursa kullanabilirsiniz. **fs.New()** diyerek **statikFS** değişkenimizi bir dosya sistemi olarak tanıttık. Daha sonra sunucu oluşturak anadizine ulaşılmak istendiğinde oluşturduğumuz dosya sistemine bağlanmasını sağladık. Artık dosya sistemimize **localhost:5555** üzerinden ulaşılabilir oldu. 42 | --------------------------------------------------------------------------------