Go 언어 문법 (Golang grammar)
1. 디렉토리 관련 함수
2021년 3월 3일 수요일 오전 8:55:31
1.1. 단일 디렉토리 생성
os.Mkdir(path, permission)
err := os.Mkdir("tmp", 0755)
if err != nil {
log.Fatal(err)
}
1.2. 다중 디렉토리 생성
os.MkdirAll(path, permission)
:
err := os.MkdirAll("tmp/new", 0755)
if err != nil {
log.Fatal(err)
}
1.3. 현재 작업 디렉토리 얻기
os.Getwd()
path, err := os.Getwd()
if err != nil {
log.Println(err)
}
fmt.Println(path)
1.4. 디렉토리 존재유무 확인
os.Stat(paht)
if _, err := os.Stat("/dirname"); os.IsNotExist(err) {
// does not exist
}
if _, err := os.Stat("/dirname"); !os.IsNotExist(err) {
// exist
}
1.5. 디렉토리 이름 바꾸기
os.Rename(oldpath, newpath)
err := os.Rename("tmp", "tmp2")
if err != nil {
log.Fatal(err)
}
2. struct 구조체 기본값 지정
2021년 3월 3일 수요일 오후 5:43:23
{
"index":0,
"value":"bar",
"result":false
}
package main
import (
"encoding/json"
"fmt"
)
type Config struct {
Index int `json:"index"`
Value string `json:"value"`
Result bool `json:"result"`
}
var data = Config{}
func main() {
con, err := ioutil.ReadFile("config.json")
if err != nil {
log.Print(err)
}
if err := json.Unmarshal(con, &data); err != nil {
log.Print(err)
}
fmt.Println(data)
}
3. Time 변수 문자열 변환 (convert time.Time to string)
2021년 3월 4일 목요일 오후 2:54:09
// caution : format string is `2006-01-02 15:04:05.000000000`
nowTime := time.Now()
fmt.Println("origin :", nowTime.String())
// origin : 2021-03-03 15:26:37.123456789 +0900 KST
fmt.Println("mm-dd-yyyy :", nowTime.Format("01-02-2006"))
// mm-dd-yyyy : 03-03-2021
fmt.Println("yyyy-mm-dd :", nowTime.Format("2006-01-02"))
// yyyy-mm-dd : 2021-03-03
// separated by .
fmt.Println("yyyy.mm.dd :", nowTime.Format("2006.01.02"))
// yyyy.mm.dd : 2021.03.03
fmt.Println("yyyy-mm-dd HH:mm:ss :", nowTime.Format("2006-01-02 15:04:05"))
// yyyy-mm-dd HH:mm:ss : 2021-03-03 15:26:37
// Stamp Micro second
fmt.Println("yyyy-mm-dd HH:mm:ss :", nowTime.Format("2006-01-02 15:04:05.000000"))
// yyyy-mm-dd HH:mm:ss : 2021-03-03 15:26:37.123456
// Stamp Nano second
fmt.Println("yyyy-mm-dd HH:mm:ss :", nowTime.Format("2006-01-02 15:04:05.000000000"))
// yyyy-mm-dd HH:mm:ss : 2021-03-03 15:26:37.123456789
4. 디렉토리 내 파일목록 읽기
2021년 3월 4일 목요일 오후 5:45:44
ioutil.ReadDir(path)
files, err := ioutil.ReadDir("tmp")
if err != nil{
fmt.Println(err)
}
for i ,f := range files {
fmt.Println(i, f.Name())
}
0 test1.txt
1 test2.txt
5. 문자열 분할
2021년 3월 8일 월요일 오전 1:21:36
Split (s, sep string ) [] string
tmp := "one_two_three"
slice := strings.Split(tmp, "_")
for i, str := range slice {
fmt.Println(i, str)
}
0 one
1 two
2 three
SplitAfter(s, sep string) []string
tmp := "one_two_three"
slice := strings.SplitAfter(tmp, "_")
for i, str := range slice {
fmt.Println(i, str)
}
0 one_
1 two_
2 three
아래의 함수는 split 횟수를 n번으로 제한하는 함수
SplitN(s, sep string, n int) []string
SplitAfterN(s, sep string, n int) []string
6. 타입 확인
2021년 3월 8일 월요일 오전 9:26:56
reflect.TypeOf(i interface{}) reflect.Type
x, y, z := 1, "2", 3.14
fmt.Println("x type :", reflect.TypeOf(x))
fmt.Println("y type :", reflect.TypeOf(y))
fmt.Println("z type :", reflect.TypeOf(z))
x type : int
y type : string
z type : float64
7. 타입 변경
strconv
7.1. 숫자 변환
Atoi : 문자열에서 int로
Itoa : int에서 문자열로
i, err := strconv.Atoi("-42")
s := strconv.Itoa(-42)
문자열을 값으로 변환
b, err := strconv.ParseBool("true")
f, err := strconv.ParseFloat("3.1415", 64)
i, err := strconv.ParseInt("-42", 10, 64)
u, err := strconv.ParseUint("42", 10, 64)
문자열을 가장 넓은 유형 (float64, int64 및 uint64)을 반환
- size 인수가 더 좁은 너비를 지정하면 결과를 데이터 손실없이 더 좁은 유형으로 변환
s := "2147483647" // biggest int32
i64, err := strconv.ParseInt(s, 10, 32)
...
i := int32(i64)
값을 문자열로 변환
s := strconv.FormatBool(true)
s := strconv.FormatFloat(3.1415, 'E', -1, 64)
s := strconv.FormatInt(-42, 16)
s := strconv.FormatUint(42, 16)
7.2. 문자열 변환
2021년 3월 8일 월요일 오전 10:14:38
문자열을 인용 된 Go 문자열 리터럴로 변환
q := strconv.Quote("Hello, World")
q := strconv.QuoteToASCII("Hello, World")
8. 에러 핸들링
2021년 3월 8일 월요일 오전 10:52:04
8.1. 복합한 에러 핸들링
빈 디렉토리 tmp 생성후 해당 코드 실행시*fs.PathError
에러가 발생하는데 아래의 switch case err.(*fs.PathError)
구문으로 별도의 에러 핸들링이 가능해진다.
dirPath := "tmp"
files, err := ioutil.ReadDir(dirPath)
switch err {
case nil:
break
case err.(*fs.PathError):
fmt.Println("[findKey] 현재 디렉토리에 파일이 없습니다.")
default:
fmt.Println("[findKey] Error :", err)
}
9. 특정 날짜/시간 동작
2021년 3월 8일 월요일 오후 1:29:32
go get github.com/robfig/cron
c := cron.New()
c.AddFunc("@midnight", func() {
findKey()
})
c.Start()
customLocation, _ := time.LoadLocation("Asia/Seoul")
c := cron.NewWithLocation(customLocation)
c.AddFunc("@midnight", func() {
fmt.Print("time :", time.Now())
})
c.Start()
10. 로그파일 작성
2021년 3월 8일 월요일 오후 1:29:32
rl, _ := rotatelogs.New(
"D:/tmp/Logfile.%Y-%m-%d.log",
rotatelogs.WithMaxAge(-1), // 정해진 시간보다 지난 파일 삭제 (-1은 비활성화)
rotatelogs.WithRotationTime(time.Hour), // 로테이션 반복 주기
rotatelogs.WithClock(rotatelogs.Local), // 로컬 시간으로 설정
rotatelogs.WithRotationCount(30), // 유지되는 파일 개수
)
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
log.SetOutput(rl)
log.Println("log write")
11. 프로젝트내 다른 로컬패키지 호출
2021년 3월 11일 목요일 오후 6:02:36
go언어는 패키지를 GOPATH 기준으로 검색하기때문에
GOPATH가 아닌 다른경로에서 프로젝트를 개발할 경우
프로젝트이름 기준으로 패키지 검색
디렉토리 구조 예시
project1
├── package1/
| └── package1.go
└── package2/
└── package2.go
11.1. 로컬패키지 호출 예시
package1.go파일에서 로컬패키지 package2 호출
./package1.go
import (
"project1/package2"
)
11.2. 잘못 사용한 예시
go언어에서는 import 구문으로 상대경로를 사용하지 않음
import (
"../package2"
)
12. uint16형 데이터 2Byte형태로 변환
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, uint16(258))
fmt.Println(string(b))
13. 서로 다른 byte 데이터 비교
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, uint16(258))
if bytes.Compare(b, []byte{1, 2}) == 0 {
fmt.Println("같은 데이터 입니다.")
}