← Back to list

Go 101

Go, Google tarafından geliştirilen, sadeliği, performansı ve güçlü concurrency desteğiyle öne çıkan açık kaynaklı bir programlama dilidir…

Ahmet Balçık · 2026-08-12 17:36 · 0 claps · 11.4 min read
#google #golang #yazılım #verimlilik #yazilim-gelistirme
Open on Medium ↗

Go 101

Go, Google tarafından geliştirilen, sadeliği, performansı ve güçlü concurrency desteğiyle öne çıkan açık kaynaklı bir programlama dilidir. 2009 yılında duyurulan Go; özellikle backend geliştirme, web servisleri, API’ler, mikroservisler, cloud altyapıları ve sistem programlama gibi alanlarda kullanılmaktadır.

GoLang logo

GoLang logo

Bu yazımda size Go diline nasıl giriş yapabileceğinizden ve temel kod parçalarından bahsedeceğim.

Klasik bir Go şablonu aşağıdaki gibidir:

package main

import "fmt"
func main() {
    fmt.Println("Hello, World!")
}

Yukarıdaki kodda aklınıza takılan bazı şeyler olabilir. Mesela “package main nedir?”, “fmt’yi neden import ediyoruz?”, “func main() ne işe yarıyor?” veya “Neden bazı satırların sonunda ; yok?" gibi.

Tüm bu sorulara aşağıda cevap bulabileceksiniz.

package main nedir?

İlk olarak kodumuzun en üstünde yer alan package main ifadesiyle başlayalım.

Go’da her .go dosyası bir package'a ait olmak zorundadır. Package'lar, kodu organize etmek ve birbiriyle ilişkili kodları bir arada tutmak için kullanılır.

Buradaki main ise özel bir package ismidir. Bir Go programını çalıştırılabilir bir uygulama olarak oluşturmak istiyorsak programın giriş noktası main package'ının içerisindeki main fonksiyonudur.

Yani aşağıdaki iki ifade birbirinden farklı kavramları temsil eder:

package main
func main() {
    // Programın çalışmaya başladığı nokta
}

Burada:

  • package main → Dosyanın main package'ına ait olduğunu belirtir.
  • func main() → Programın başlangıç noktasıdır.

Peki Go’da her zaman package main olmak zorunda mı?

Hayır.

Go’da farklı amaçlar için farklı package’lar oluşturabiliriz. Örneğin kullanıcı işlemlerini yöneten user isimli bir package oluşturabiliriz:

package user
type User struct {
    Name string
}

Yukarıdaki durumda dosyamız user package'ına aittir. main package'ından farklı olarak burada main() fonksiyonuna ihtiyacımız yoktur.

Dolayısıyla önemli ayrım şu:

*package main, çalıştırılabilir bir Go programının package'ıdır. func main(), programın çalışmaya başladığı giriş noktasıdır.*

import "fmt" neden var?

İlk kodumuzda yer alan import "fmt" ifadesini fark etmişsinizdir.

Burada Go’nun import keyword'ünü kullanıyoruz.

Bir package içerisinde bulunan fonksiyonları, tipleri veya diğer öğeleri kullanabilmek için ilgili package’ı import etmemiz gerekir.

Peki fmt nedir?

fmt, Go'nun standart kütüphanesinde bulunan package'lardan biridir. Temel olarak formatlı input/output işlemleri için kullanılır.

Bizim örneğimizde ise terminale yazı yazdırmak için fmt package'ını kullanıyoruz:

fmt.Println("Hello, World!")

Buradaki yapıyı parçalarsak:

fmt      → kullandığımız package
.        → package içerisindeki bir öğeye erişim
Println  → çağırdığımız fonksiyon

Yani bu ifade kısaca:

*“fmt package'ının içerisindeki Println fonksiyonunu çağır."*

anlamına gelir.

Neden fmt'yi import etmek zorundayız?

Çünkü Println bizim yazdığımız bir fonksiyon değil. Go'nun standart kütüphanesinde bulunan fmt package'ının içerisinde yer alıyor.

Örneğin:

package main

func main() {
    Println("Hello, World!")
}

şeklinde yazarsak Go, Println fonksiyonunun ne olduğunu bilemez ve hata verir.

Doğru kullanım:

package main

import "fmt"
func main() {
    fmt.Println("Hello, World!")
}

Burada ayrıca Go’nun önemli bir kuralıyla karşılaşıyoruz:

Import ettiğimiz bir package’ı kullanmak zorundayız.

Örneğin:

package main

import "fmt"
func main() {
}

kodunu çalıştırdığımızda Go hata verecektir. Çünkü fmt import edilmiş olmasına rağmen kullanılmamıştır.

Go, kullanılmayan import’lara izin vermez. Bu yaklaşım ilk başta biraz katı görünse de kod içerisinde gereksiz import’ların birikmesini engeller.

func main() nedir?

Şimdi programımızın asıl giriş noktasına geldik:

func main() {
    fmt.Println("Hello, World!")
}

Buradaki func, bir fonksiyon tanımladığımızı belirtir.

main ise fonksiyonun ismidir.

Parantezler:

()

fonksiyonun parametrelerini belirtmek için kullanılır. Bizim main fonksiyonumuz herhangi bir parametre almadığı için parantezlerin içi boştur.

Süslü parantezler ise:

{
    ...
}

fonksiyonun gövdesini belirtir.

Dolayısıyla:

func main() {
    fmt.Println("Hello, World!")
}

ifadesini şu şekilde okuyabiliriz:

*“main adında, parametre almayan bir fonksiyon tanımla ve içerisinde bulunan kodları çalıştır."*

Go programımız çalıştırıldığında main package'ının main fonksiyonu programın giriş noktası olarak çalıştırılır.

fmt.Println ne yapıyor?

Son olarak programımızın gerçekten iş yapan satırına bakalım:

fmt.Println("Hello, World!")

Println, verilen değerleri standart çıktıya yazdırır ve sonuna yeni satır ekler.

Örneğin:

fmt.Println("Hello")
fmt.Println("World")

çıktısı:

Hello
World

olacaktır.

Println dışında fmt package'ında sık kullanacağımız başka fonksiyonlar da vardır:

fmt.Print("Hello")
fmt.Println("Hello")
fmt.Printf("Hello %s", "World")

Print yeni satır eklemeden çıktı verir.

Println çıktının sonuna yeni satır ekler.

Printf ise belirli bir format kullanarak çıktı oluşturmamızı sağlar.

Örneğin:

name := "Ahmet"

fmt.Printf("Merhaba %s\n", name)

çıktısı:

Merhaba Ahmet

olacaktır.

Buradaki %s, string bir değer yerleştirmek için kullanılan format belirtecidir.

İlk Go programımızı artık okuyabiliriz

Şu ana kadar öğrendiklerimizle ilk programımıza tekrar bakalım:

package main

import "fmt"
func main() {
    fmt.Println("Hello, World!")
}

Programımızın akışı kabaca şöyledir:

  1. Dosya main package'ına aittir.
  2. fmt package'ı kullanılmak üzere import edilir.
  3. Programın giriş noktası olan main fonksiyonu tanımlanır.
  4. fmt.Println ile terminale Hello, World! yazdırılır.

Birkaç satırlık basit bir kod gibi görünse de Go’nun temel çalışma mantığının önemli bir kısmını bu küçük örnekte görmüş olduk.

Şimdi biraz da Go’nun syntax kurallarına bakalım.

Go Syntax Kuralları

Bir programlama dilini öğrenirken sadece keyword’leri bilmek yeterli değildir. Dilin syntax kurallarını da bilmemiz gerekir.

Go bu konuda oldukça sade bir yapıya sahiptir. Ancak başka dillerden gelen geliştiricilerin dikkat etmesi gereken bazı farklılıklar bulunur.

Noktalı virgül ; kullanmak zorunda mıyız?

Go kodlarında çoğu zaman satırların sonunda ; görmeyiz.

Örneğin:

fmt.Println("Hello")
fmt.Println("World")

şeklinde yazabiliriz.

Java, C veya JavaScript gibi dillerde sıkça karşılaştığımız:

fmt.Println("Hello");

kullanımı Go’da genellikle gerekli değildir.

Go, belirli kurallara göre satır sonlarında semicolon’ları otomatik olarak ekler.

Bu nedenle günlük Go kodunda ; yazmayız.

{} kullanımı

Go’da süslü parantezler kod bloklarını belirtmek için kullanılır.

Örneğin:

if age >= 18 {
    fmt.Println("Adult")
}

Burada { ifadesi koşula ait kod bloğunun başladığını belirtir.

Go’da dikkat edilmesi gereken önemli bir syntax kuralı vardır.

Aşağıdaki kullanım doğru değildir:

if age >= 18
{
    fmt.Println("Adult")
}

Go’da { karakteri ilgili statement ile aynı satırda bulunmalıdır:

if age >= 18 {
    fmt.Println("Adult")
}

Bu küçük bir detay gibi görünse de Go öğrenirken sık karşılaşabileceğiniz kurallardan biridir.

if içerisinde parantez kullanmalı mıyız?

Go’da if koşullarının etrafına parantez koymamıza gerek yoktur.

Örneğin:

if age >= 18 {
    fmt.Println("Adult")
}

yeterlidir.

Şu kullanım ise Go’nun tercih ettiği syntax değildir:

if (age >= 18) {
    fmt.Println("Adult")
}

Go’nun tasarımındaki temel fikirlerden biri gereksiz syntax’ı azaltmaktır.

Büyük ve küçük harf önemli mi?

Evet.

Go case-sensitive bir dildir.

Yani:

name

ile:

Name

aynı şey değildir.

Örneğin:

var name string
var Name string

iki farklı değişken tanımlar.

Ancak Go’da büyük ve küçük harf konusu sadece değişken isimleri açısından önemli değildir. Package’lar arasındaki erişim açısından da önemli bir anlam taşır.

Örneğin:

type User struct {
    Name string
}

Buradaki Name büyük harfle başladığı için başka package'lardan erişilebilir.

Buna karşılık:

type User struct {
    name string
}

şeklinde yazarsak name package dışından doğrudan erişilebilir olmaz.

Go’da bu konuya exported ve unexported kavramlarıyla ilerleyen bölümlerde daha detaylı değineceğiz.

Değişkenler

Artık kodumuzda veri tutmaya başlayabiliriz.

Go’da değişken tanımlamanın birkaç farklı yolu vardır.

En temel yöntem:

var name string = "Ahmet"

Burada:

  • var → değişken tanımladığımızı belirtir.
  • name → değişkenin ismidir.
  • string → değişkenin tipidir.
  • "Ahmet" → değişkene verdiğimiz değerdir.

Daha kısa bir kullanım da vardır:

var name = "Ahmet"

Burada Go, değere bakarak değişkenin tipini kendisi belirler.

Buna type inference denir.

Bir diğer ve Go’da oldukça sık kullanılan yöntem ise := operatörüdür:

name := "Ahmet"

Bu ifade:

var name string = "Ahmet"

ile benzer şekilde çalışır.

= ile := arasındaki fark nedir?

Bu ikisi yeni başlayanların en çok karıştırdığı konulardan biridir.

= mevcut bir değişkene değer atamak için kullanılır:

name := "Ahmet"

name = "Mehmet"

İlk satırda değişkeni oluşturduk.

İkinci satırda ise mevcut değişkenin değerini değiştirdik.

:= ise yeni bir değişken tanımlamak için kullanılır:

name := "Ahmet"

Bu nedenle:

name = "Ahmet"

ile:

name := "Ahmet"

aynı şey değildir.

:= kullanarak yeni bir değişken oluşturduğunuzda Go, değişkenin tipini sağ taraftaki değerden çıkarır.

:= her yerde kullanılabilir mi?

Hayır.

:= sadece bir fonksiyonun içerisinde yeni değişken tanımlarken kullanılabilir.

Örneğin:

func main() {
    name := "Ahmet"
}

geçerlidir.

Ancak package seviyesinde:

package main

name := "Ahmet"

kullanımı geçerli değildir.

Package seviyesinde var kullanabiliriz:

package main

var name = "Ahmet"

Sabitler — const

Değeri program boyunca değişmemesi gereken durumlarda const kullanabiliriz.

Örneğin:

const pi = 3.14

Artık:

pi = 5

yapamayız.

Başka bir örnek:

const appName = "My Application"

Constant’lar özellikle program içerisinde değişmemesi gereken değerleri tanımlamak için kullanılır.

Temel Veri Tipleri

Go statik tipli bir dildir.

Yani bir değişkenin tipi belirlenir ve bu tip ile uyumlu değerler kullanılması beklenir.

En sık karşılaşacağımız temel veri tiplerinden bazıları şunlardır:

string
int
float64
bool

Örneğin:

var name string = "Ahmet"
var age int = 25
var price float64 = 99.99
var isActive bool = true

Burada:

  • string → metinsel değerler
  • int → tam sayılar
  • float64 → ondalıklı sayılar
  • booltrue veya false değerleri

için kullanılır.

Tip sonradan değiştirilebilir mi?

Hayır.

Örneğin:

age := 25
age = "Ahmet"

kodumuz hata verecektir.

Çünkü age değişkeni oluşturulduğunda Go bunun int olduğunu belirlemiştir.

Bir int değişkene string değer atayamayız.

Bu durum Go’nun statik tip sisteminin bir sonucudur.

Fonksiyonlar

Kodumuzu tekrar kullanılabilir parçalara ayırmak için fonksiyonları kullanırız.

Basit bir fonksiyon:

func sayHello() {
    fmt.Println("Hello")
}

Burada func keyword'ü bir fonksiyon tanımladığımızı belirtir.

Fonksiyonumuzu daha sonra çağırabiliriz:

func main() {
    sayHello()
}

Çıktı:

Hello

Fonksiyon parametreleri

Fonksiyonlara dışarıdan veri gönderebiliriz.

Örneğin:

func sayHello(name string) {
    fmt.Println("Hello", name)
}

Artık:

sayHello("Ahmet")

şeklinde çağırabiliriz.

Buradaki name string fonksiyonun bir parametre aldığını belirtir.

Fonksiyonlar değer döndürebilir

Fonksiyonlar sadece işlem yapmakla kalmaz, sonuç da döndürebilir.

Örneğin:

func add(a int, b int) int {
    return a + b
}

Burada son taraftaki:

int

fonksiyonun int tipinde bir değer döndüreceğini belirtir.

Kullanımı:

result := add(10, 20)

fmt.Println(result)

çıktısı:

30

olacaktır.

Go’da aynı tipteki parametreleri daha kısa da yazabiliriz:

func add(a, b int) int {
    return a + b
}

Bu iki kullanım aynıdır.

Birden Fazla Değer Döndürmek

Go’nun diğer birçok programlama dilinden ayrıldığı özelliklerden biri, fonksiyonların birden fazla değer döndürebilmesidir.

Örneğin:

func divide(a, b int) (int, int) {
    return a / b, a % b
}

Bu fonksiyondan iki farklı değer döndürüyoruz.

Kullanımı:

result, remainder := divide(10, 3)

fmt.Println(result)
fmt.Println(remainder)

çıktısı:

3
1

şeklinde olacaktır.

Bu özellik özellikle Go’da error handling konusunda çok sık karşımıza çıkacaktır.

Koşullar — if

Programlarımızda belirli bir koşula göre farklı işlemler yapmak isteyebiliriz.

Bunun için if kullanılır:

age := 20

if age >= 18 {
    fmt.Println("Adult")
}

Koşul doğruysa kod bloğu çalışır.

else ile alternatif bir durum belirleyebiliriz:

if age >= 18 {
    fmt.Println("Adult")
} else {
    fmt.Println("Minor")
}

Birden fazla koşul için else if kullanabiliriz:

if age >= 65 {
    fmt.Println("Senior")
} else if age >= 18 {
    fmt.Println("Adult")
} else {
    fmt.Println("Minor")
}

Go’da while nerede?

Go öğrenirken bu soru oldukça sık sorulur.

C, Java veya Python gibi dillerde ayrı bir while yapısı bulunabilir.

Go’da ise ayrı bir while keyword'ü yoktur.

Bunun yerine for kullanılır.

Örneğin:

for age < 18 {
    age++
}

Bu yapı while mantığıyla çalışır.

for Döngüsü

Go’da döngüler için for kullanılır.

Klasik kullanım:

for i := 0; i < 5; i++ {
    fmt.Println(i)
}

Çıktı:

0
1
2
3
4

Burada:

i := 0

başlangıç değeridir.

i < 5

döngünün devam etme koşuludur.

i++

ise her iterasyondan sonra çalıştırılır.

Go’da sonsuz döngü de oluşturabiliriz:

for {
    fmt.Println("Running...")
}

Bu döngüyü break ile sonlandırabiliriz:

for {
    fmt.Println("Running...")
    break
}

Array

Birden fazla aynı tipteki veriyi bir arada tutmak istediğimizde array kullanabiliriz.

Örneğin:

numbers := [3]int{10, 20, 30}

Buradaki:

[3]int

ifadesi 3 elemanlı bir int array'i olduğunu belirtir.

Elemanlara index üzerinden ulaşabiliriz:

fmt.Println(numbers[0])
fmt.Println(numbers[1])
fmt.Println(numbers[2])

Çıktı:

10
20
30

Go’da index’ler 0'dan başlar.

Slice

Go’da array ile birlikte çok sık kullanacağımız bir diğer yapı slice’tır.

Örneğin:

numbers := []int{10, 20, 30}

Burada array’den farklı olarak boyutu başlangıçta sabit bir yapı oluşturmuyoruz.

Yeni eleman ekleyebiliriz:

numbers = append(numbers, 40)

Artık:

[10 20 30 40]

değerine sahibiz.

Slice’lar Go’da oldukça sık kullanılır.

Array ve slice arasındaki temel farklardan biri, array’in uzunluğunun tipinin bir parçası olmasıdır:

[3]int
[5]int

bunlar farklı tiplerdir.

Slice ise:

[]int

şeklindedir ve dinamik olarak büyüyebilir.

Map

Bir key-value yapısına ihtiyaç duyduğumuzda map kullanabiliriz.

Örneğin:

users := map[string]int{
    "Ahmet": 25,
    "Mehmet": 30,
}

Burada:

string → key
int    → value

olarak kullanılmıştır.

Veriye key üzerinden ulaşabiliriz:

fmt.Println(users["Ahmet"])

çıktısı:

25

Yeni bir değer eklemek de oldukça kolaydır:

users["Ayşe"] = 28

Artık map içerisinde Ayşe de bulunmaktadır.

Bir key’in map içerisinde olup olmadığını kontrol etmek için ise:

age, ok := users["Ahmet"]

if ok {
    fmt.Println(age)
}

şeklinde bir kullanım görebiliriz.

Buradaki ok değeri, key'in bulunup bulunmadığını belirtir.

Struct

Go’da farklı veri tiplerini tek bir yapı altında toplamak için struct kullanabiliriz.

Örneğin bir kullanıcıyı temsil etmek istediğimizi düşünelim:

type User struct {
    Name string
    Age  int
}

Burada User isimli yeni bir struct tipi oluşturduk.

Artık bir kullanıcı oluşturabiliriz:

user := User{
    Name: "Ahmet",
    Age:  25,
}

Değerlerine ise:

fmt.Println(user.Name)
fmt.Println(user.Age)

şeklinde ulaşabiliriz.

Struct’ları özellikle gerçek dünyadaki varlıkları kod içerisinde modellemek için sıkça kullanacağız.

Örneğin:

type Product struct {
    Name  string
    Price float64
    Stock int
}

gibi bir yapı oluşturabiliriz.

Method

Struct’lar ile birlikte method kavramıyla da karşılaşacağız.

Örneğin:

type User struct {
    Name string
}

Bu struct’a ait bir method tanımlayabiliriz:

func (u User) SayHello() {
    fmt.Println("Hello", u.Name)
}

Artık:

user := User{
    Name: "Ahmet",
}

user.SayHello()

yazabiliriz.

Çıktı:

Hello Ahmet

Buradaki:

(u User)

kısmına receiver denir.

Bu sayede SayHello fonksiyonunun User tipine ait bir method olduğunu belirtmiş oluruz.

Pointer nedir?

Pointer konusu Go öğrenmeye başlayanlar için ilk başta biraz kafa karıştırıcı olabilir.

Temel olarak pointer, bir değerin bellekteki adresini tutmamızı sağlar.

Örneğin:

age := 25
ptr := &age

Buradaki &, age değişkeninin adresini almamızı sağlar.

Pointer’ın gösterdiği değere ise * ile ulaşabiliriz:

fmt.Println(*ptr)

çıktısı:

25

Pointer’lar özellikle bir fonksiyon içerisinde gönderilen değerin kendisini değiştirmek istediğimiz durumlarda karşımıza çıkar.

Örneğin:

func changeAge(age *int) {
    *age = 30
}

Kullanımı:

age := 25
changeAge(&age)
fmt.Println(age)

çıktısı:

30

Burada fonksiyona age değişkeninin kendisini değil, bellekteki adresini gönderdik.

Pointer konusu bundan çok daha detaylıdır ancak başlangıç seviyesinde bilmemiz gereken temel mantık budur.

Error Handling

Go’nun en karakteristik özelliklerinden biri error handling yaklaşımıdır.

Birçok programlama dilinde hata yönetimi için try/catch gibi yapılar kullanılır.

Go’da ise hatalar genellikle fonksiyonlardan normal bir değer gibi döndürülür.

Örneğin:

result, err := doSomething()
if err != nil {
    return err
}

Burada err bir hata olup olmadığını kontrol etmek için kullanılır.

Go’da error, özel bir interface'tir.

Bir fonksiyon hata oluşturabilecekse genellikle sonucu ve hatayı birlikte döndürür:

func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("cannot divide by zero")
    }
    return a / b, nil
}

Kullanımı:

result, err := divide(10, 0)

if err != nil {
    fmt.Println("Error:", err)
    return
}
fmt.Println(result)

Burada:

if err != nil

ifadesini Go kodlarında çok sık göreceğiz.

nil kabaca "değer yok" anlamında düşünülebilir.

Dolayısıyla:

err != nil

ifadesi:

“Bir hata var mı?”

kontrolünü yapar.

Hata yoksa genellikle:

err == nil

olur.

Bu yaklaşım Go’da oldukça yaygındır:

result, err := someFunction()
if err != nil {
    return err
}

İlk başta tekrar tekrar aynı yapıyı yazmak biraz fazla gelebilir. Ancak Go’nun error handling yaklaşımının temel amacı hataları açık ve kontrol edilebilir bir şekilde ele almaktır.

nil nedir?

nil, Go'da bazı tipler için "değer yok" durumunu temsil eder.

Örneğin pointer:

var ptr *int
fmt.Println(ptr)

değeri nil olabilir.

Benzer şekilde bazı durumlarda:

  • pointer
  • slice
  • map
  • function
  • interface
  • channel

gibi tiplerde nil kullanılabilir.

Ancak önemli bir nokta var: Her veri tipi nil alamaz.

Örneğin:

var age int = nil

geçerli değildir.

Çünkü int, nil alabilen bir tip değildir.

Package Yapısı

Başta package konusuna değinmiştik. Şimdi biraz daha gerçek bir proje yapısına bakalım.

Örneğin projemiz şu şekilde olabilir:

myproject/
├── go.mod
├── main.go
└── user/
    └── user.go

main.go:

package main

import (
    "fmt"
    "myproject/user"
)
func main() {
    u := user.User{
        Name: "Ahmet",
    }
    fmt.Println(u.Name)
}

user/user.go:

package user

type User struct {
    Name string
}

Burada main package'ı içerisinden user package'ını import ediyoruz.

Dikkat ederseniz User büyük harfle başlıyor:

type User struct

Bu önemli.

Go’da bir identifier büyük harfle başlıyorsa başka package’lar tarafından erişilebilir hale gelir.

Örneğin:

type User struct {
    Name string
}

kullanılabilirken:

type user struct {
    name string
}

package dışından doğrudan erişilebilir değildir.

Bu konu Go’da export mantığının temelini oluşturur.

Go Modules ve go.mod

Go projelerinde dependency yönetimi ve module bilgilerini go.mod dosyası üzerinden yönetiriz.

Yeni bir proje oluşturduğumuzda:

go mod init myproject

komutunu çalıştırabiliriz.

Bunun sonucunda:

go.mod

dosyası oluşur.

Basit bir go.mod dosyası şu şekilde görünebilir:

module myproject
go 1.24

Buradaki module, projenin module path'ini belirtir.

Go Modules konusu özellikle dışarıdan dependency eklemeye başladığımızda daha önemli hale gelir.

Go’nun Temel Komutları

Go ile çalışırken terminalde bazı komutları sürekli kullanacağız.

go run

Programı derleyip çalıştırmak için:

go run .

kullanabiliriz.

Örneğin:

go run main.go

şeklinde de çalıştırabiliriz.

go build

Programı derlemek için:

go build

kullanılır.

Bu komut kaynak kodumuzu derleyerek çalıştırılabilir bir binary oluşturabilir.

go fmt

Go’nun en güzel özelliklerinden biri kod formatlama konusunda standart bir araç sunmasıdır.

go fmt

komutuyla Go kodumuzu standart formata göre düzenleyebiliriz.

Örneğin kodu şu şekilde yazmış olsak bile:

func main(){fmt.Println("Hello")}

gofmt bunu standart Go formatına dönüştürür:

func main() {
    fmt.Println("Hello")
}

Bu nedenle Go projelerinde kod formatı konusunda çok fazla tartışma yaşamayız.

go test

Go’nun kendi içerisinde test framework’ü bulunur.

Testleri çalıştırmak için:

go test

veya proje içerisindeki tüm package’ları test etmek için:

go test ./...

kullanabiliriz.

Test konusu bu yazının kapsamının dışında olduğu için burada sadece temel komutu bilmemiz yeterli.

go mod tidy

Projedeki dependency’leri düzenlemek için:

go mod tidy

komutunu kullanabiliriz.

Kullanılmayan dependency’leri temizler ve gerekli dependency bilgilerini go.mod ve go.sum dosyalarına göre düzenler.

Sonuç

Bu yazıda Go ile ilk karşılaştığımız kodun aslında ne anlama geldiğini adım adım incelemeye çalıştık.

Başlangıçta sadece birkaç satırdan oluşan şu kod vardı:

package main

import "fmt"
func main() {
    fmt.Println("Hello, World!")
}

Ancak bu birkaç satırın içerisinde bile Go’nun temel yapı taşlarının önemli bir kısmı bulunuyor.

Artık:

  • package main nedir,
  • package ne işe yarar,
  • import neden kullanılır,
  • fmt nedir,
  • fmt.Println ne yapar,
  • func main() nedir,
  • Go’da syntax kuralları nasıldır,
  • var ve := arasındaki fark nedir,
  • const ne işe yarar,
  • temel veri tipleri nelerdir,
  • fonksiyonlar nasıl tanımlanır,
  • fonksiyonlar nasıl değer döndürür,
  • if ve for nasıl kullanılır,
  • array ve slice arasındaki temel fark nedir,
  • map nedir,
  • struct ve method nedir,
  • pointer’ın temel mantığı nedir,
  • Go’da error handling nasıl yapılır,
  • package’lar nasıl organize edilir,
  • Go Modules nedir,
  • temel go komutları nelerdir

gibi soruların cevaplarını biliyoruz.

Fakat Go’nun asıl güçlü taraflarından henüz bahsetmedik.

Go’yu backend ve cloud dünyasında bu kadar popüler yapan konuların başında goroutine, channel ve concurrency modeli geliyor.

Bir sonraki yazıda Go’nun en çok konuşulan özelliklerinden biri olan concurrency konusuna geçerek goroutine ve channelyapılarını inceleyeceğiz.

Go 101 serisinin bir sonraki bölümü olursa orada görüşmek üzere :)


메타데이터
post_id
51db4e27d142
slug
go-101-51db4e27d142
url
https://medium.com/@ahmet.balcik.official/go-101-51db4e27d142
canonical_url
https://medium.com/@ahmet.balcik.official/go-101-51db4e27d142
author_url
https://medium.com/@ahmet.balcik.official
status
ok
fetched_at
2026-08-23 03:47:58