Main Package

go언어는 반드시 환경 변수의 GOPATH 경로에서만 프로젝트를 생성할 수 있으며, package main에서만 컴파일이 가능하다.
package mainfunc main() 함수를 우선적으로 컴파일 한다.

Packages and Imports

어떤 함수를 export하고 싶다면 함수의 시작이 대문자여야한다.

package something

import "fmt"

func sayBye() {
	fmt.Println("bye")
}

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

package main

import (
	"fmt"

	"github.com/y00913/learngo/something"
)

func main() {
	fmt.Println("Hello world")
	something.SayHello      //대문자이기 때문에 사용 가능
        something.sayHello      //소문자이기 때문에 사용 불가 (private)
}

Variables and Constants

상수는 const, 변수는 var로 시작하며 반드시 type을 선언해야한다.
변수의 타입 선언은 축약이 가능하다. (상수는 불가) 그러나 func 밖에서는 사용할 수 없다.

package main

import "fmt"

func main() {
	const name string = "nico"
	name = "lynn"       //상수이기 때문에 불가
	fmt.Println(name)
}

package main

import "fmt"

var tf bool = false     //func 밖에서는 축약형 사용 불가

func main() {
	var name string = "nico"
	name = "lynn"       //변수이기 때문에 가능
	fmt.Println(name)

	name2 := "nico"     //변수의 타입 선언 축약형
	fmt.Println(name2)
}

Functions part One

함수의 변수와 리턴값들에게 반드시 타입을 선언해야 한다.
함수의 변수 타입이 같다면 동시에 선언할 수 있다.
사용하지 않는 import가 있다면 컴파일되지 않는다.

package main

import "fmt"

func multiply(a, b int) int {       //func multiply(a int, b int)
	return a * b
}

func main() {
	fmt.Println(multiply(2, 2))
}

go언어의 함수는 동시에 여러 개의 값들을 리턴할 수 있다.
사용하지 않는 리턴 값은 _를 이용하여 무시할 수 있다.

package main

import (
	"fmt"       //사용하지 않는 import가 있는 지 주의
	"strings"
)

func lenAndUpper(name string) (int, string) {
	return len(name), strings.ToUpper(name)     //strings.ToUpper는 대문자로 바꿔주는 package
}                                                   //동시에 두개의 값을 리턴할 수 있음

func main() {
	totalLength, upperName := lenAndUpper("nico")
	fmt.Println(totalLength, upperName)

        totalLength2, _ := lenAndUpper("nico")      //'_'를 통해 두번째 리턴값 무시
        fmt.Println(totalLength2)
}

배열의 값들을 순서대로 불러올려면 ...string을 사용한다.

package main

import (
	"fmt"
)

func repeatMe(words ...string) {        //foreach와 유사
	fmt.Println(words)
}

func main() {
	repeatMe("nico", "lynn", "dal", "marl", "flynn")
}

Functions part Two

함수의 리턴값의 타입을 선언할 때 변수도 함께 선언해주면 리턴할 때 값을 명시하지 않아도 된다.
defer는 함수가 값을 리턴하고 나면 실행한다. 개인적으로 가장 마음에 드는 기능이다.

package main

import (
	"fmt"
	"strings"
)

func lenAndUpper(name string) (lenght int, uppercase string) {      //리턴 값 명시
        defer fmt.Println("I'm done")       //함수가 값을 리턴한 후 실행
	lenght = len(name)
	uppercase = strings.ToUpper(name)
	return      //이미 값이 명시되어서 명시가 필요 없음
}

func main() {
	totalLength, upperName := lenAndUpper("nico")
	fmt.Println(totalLength, upperName)
}

for, range, …args

go언어는 오직 for만 존재한다.
range는 배열의 값들을 순회할 때 사용되며 (foreach와 유사) 이때 for문에서는 순회하는 위치의 index와 값을 출력한다.

package main

import (
	"fmt"
)

func superAdd(numbers ...int) int {
	for index, number := range numbers {        //_, number도 사용 가능
		fmt.Println(index, number)
	}
	return 1
}

func main() {
	superAdd(1, 2, 3, 4, 5, 6)
}

for문의 변수가 하나일 경우 index만 출력하게 된다.

        for number := range numbers{        //이럴 경우 index가 출력됨
		fmt.Println(number)
	}

for문은 아래 방식으로도 선언이 가능하다.

        for i := 0; i < len(numbers); i++ {     //이러한 방식으로도 for 선언 가능
	        fmt.Println(numbers[i])
        }