package main
import "fmt" // 파일 입출력 관련 표준 라이브러리 패키지
func main() {
println("Hello World")
/* 1. Variable */
var i, j, k int = 1, 2, 3 // mismatch 주의
var tmp int // 기본값은 0
v: = 999 // 타입 추론 및 func 내 var 생략
println(i)
println(j)
println(k)
println(tmp)
println(v)
/* 2. Constant */
const (
Visa = "Visa"
Master = "MasterCard"
Amex = "American Express"
)
const (
Apple = iota // 0
Grape // 1
Orange // 2
)
println(Visa)
println(Apple)
/* 3. Data Type */
// bool
// string (immutable)
// int, int8, int16, int 64
// uint uint8 uint16 uint32 uint64 uintptr
// float32 float64 complex64 complex128
// byte: uint8과 동일하며 바이트 코드에 사용
// rune: int32과 동일하며 유니코드 코드포인트에 사용한다
/* 4. String */
// Raw String Literal. 복수라인에 주로 사용된다.
rawLiteral: = `아리랑\n
아리랑\n
아라리요`
// Interpreted String Literal
interLiteral: = "아리랑아리랑\n아리리요"
// 아래와 같이 +를 사용하여 두 라인에 걸쳐 사용할 수도 있다.
// interLiteral := "아리랑아리랑\n" +
// "아리리요"
fmt.Println(rawLiteral)
fmt.Println()
fmt.Println(interLiteral)
/* 5. Type Conversion */
var x5 int = 100
var y5 uint = uint(x5)
var z5 float32 = float32(y5)
println(z5, y5)
str5: = "ABC"
bytes: = [] byte(str5)
strCovt: = string(bytes)
println(bytes, strCovt)
/* 6. Operator */
// Pointer op
var k6 int = 10
var ptr = & k6 //k의 주소를 할당
println(ptr)
println( * ptr) //p가 가리키는 주소에 있는 실제 내용을 출력
/* 7. if statement */
i7: = 2
if i7 == 1 { //같은 라인
println("One")
} else if i7 == 2 { //같은 라인
println("Two")
} else { //같은 라인
println("Other")
}
// if 문에서 조건식 사용하기 전에 Optional Statement가 가능하다.
max: = 100
if v7: = i7 * 2;
v7 < max {
println(v7)
}
/* 8. Switch statement */
var name string
var category = 2
switch category {
case 1:
name = "Paper Book"
case 2:
name = "eBook"
case 3, 4: // 콤마를 통해 복수개의 case 값 적용 가능
name = "Blog"
default:
name = "Other"
}
println(name)
// Expression을 사용한 경우
// switch x := category << 2; x - 1 {
// ...
// }
// Go만의 특별한 용법들
// 1. switch 뒤에 expression이 없을 수 있음
// 2. case문에 expression을 쓸 수 있음
// 3. No default fall through (break 없어도 다른 case 문으로 가지 않는다)
// 4. Type switch
// 3번의 경우, fallthrough를 명시해주어 다음 case로 넘어갈 수 있고,
// 4번의 경우, 아래와 같이 활용한다.
explain: = func(i interface {}) {
switch t: = i.(type) {
case bool:
fmt.Println("I'm a bool")
case int:
fmt.Println("I'm an int")
case string:
fmt.Println("I'm a string")
default:
fmt.Printf("Don't know type %T\n", t)
}
}
explain(name)
/* 9. for loop statement */
sum: = 0
for i: = 1;
i <= 100;
i++{ // 괄호 ()를 쓰면 에러가 발생한다.
sum += i
}
println(sum)
i9: = 1
for i9 < 100 { // 조건만 작성하여 while처럼 사용할 수 있다.
i9 *= 2
//if i9 > 90 {
// break
//}
}
println(i9)
// 무한 루프는 조건 없이 for만 적는다.
// for {
// println("Infinite loop")
// }
// for range 문이 가능하다
names: = [] string {
"홍길동", "이순신", "강감찬"
}
for index, name: = range names {
println(index, name)
}
// 그 외에 break, continue, goto 문이 사용된다.
}
package main
import (
"fmt"
)
/* 익명 함수 관련 내용 추가 */
// 함수 원형 정의
type calculatorNum func(int, int) int
type calculatorStr func(string, string) string
func calNum(f calculatorNum, a int, b int) int {
result: = f(a, b)
return result
}
func calStr(f calculatorStr, a string, b string) string {
sentence: = f(a, b)
return sentence
}
func main() {
/* 1. Function */
msg: = "Hello World"
say(msg)
/* 2. Pass By Reference */
addExclamation( & msg)
say(msg)
/* 3. Variadic Function */
says("Hello", "New", "World")
/* 4. Function Return */
total: = sum(1, 7, 3, 5, 9)
println(total)
count,
total: = sums(1, 7, 3, 5, 9)
println(count, total)
/* 5. Anonymous Function */
// 함수 전체를 변수에 할당하거나 다른 함수의 파라미터에 직접 정의된다.
// '변수명(파라미터들)' 형태로 사용된다.
// 일급 함수 -> 기본 타입과 동일하게 취급 -> 함수의 파라미터 전달 혹은 리턴값으로 사용된다.
// type문을 사용한 함수 원형 정의
multi: = func(i int, j int) int {
return i * j
}
duple: = func(i string, j string) string {
return i + j + i + j
}
r1: = calNum(multi, 10, 20)
fmt.Println(r1)
r2: = calStr(duple, "Hello", " Golang ")
fmt.Println(r2)
/* 6. Closure */
next: = nextValue()
println(next()) // 1
println(next()) // 2
println(next()) // 3
anotherNext: = nextValue()
println(anotherNext()) // 1 다시 시작
println(anotherNext()) // 2
/* 7. Go Collection - Array */
var arr1[3] int
arr1[0] = 1
arr1[1] = 2
arr1[2] = 3
println(arr1[2])
var arr2 = [3] int {
1, 2, 3
}
var arr3 = [...] int {
4, 5, 6
}
fmt.Println(arr2)
fmt.Println(arr3[2])
var a = [2][3] int {
{
1, 2, 3
}, {
4, 5, 6
}, //끝에 콤마 추가
}
println(a[1][2])
/* 7. Go Collection - Slice */
// Go 배열은 크기를 동적으로 증가시키거나 부분 배열을 발췌하는 등의 기능이 없다.
// Go Slice는 내부적으로 배열에 기초하여 만들어졌지만,
// 이런 제약점들을 넘어 편리하고 유용한 기능을 제공한다.
var s1[] int // 슬라이스 변수 선언 (크기를 지정하지 않는다)
s1 = [] int {
1, 2, 3
}
s1[1] = 10
fmt.Println(s1)
// make를 활용하여 슬라이스 생성
s2: = make([] int, 5, 10) // Slice type, Length, Capacity
println(len(s2), cap(s2))
// 부분 슬라이스
s3: = [] int {
0, 1, 2, 3, 4, 5
}
s3 = s3[2: 5] // 2, 3, 4
s3 = s3[1: ] // 3, 4
fmt.Println(s3) // 3, 4 출력
// 슬라이스 병합과 복사
s4: = [] int {
0, 1
}
// 하나 확장
s4 = append(s4, 2) // 0, 1, 2
// 복수 요소들 확장
s4 = append(s4, 3, 4, 5) // 0,1,2,3,4,5
fmt.Println(s4)
/* 8. Go Collection - Map */
tickers: = map[string] string {
"GOOG": "Google Inc",
"MSFT": "Microsoft",
"FB": "Facebook",
}
println(tickers["GOOG"])
// 추가 혹은 갱신
tickers["NV"] = "NAVER"
tickers["FB"] = "FaceBook"
fmt.Println(tickers)
noData: = tickers["KKO"] // 값이 없으면 nil 혹은 zero 리턴
println(noData)
// 삭제
delete(tickers, "FB")
fmt.Println(tickers)
// map 키 체크
val,
exists: = tickers["MSFTS"]
if !exists {
println("No MSFT ticker")
} else {
fmt.Printf("Value is %s", val)
}
// for range 문을 사용하여 모든 맵 요소 출력
// Map은 unordered 이므로 순서는 무작위
for key,
val: = range tickers {
fmt.Println(key, val)
}
}
// Pass By Value
func say(msg string) {
println(msg)
}
// Pass By Reference
func addExclamation(msg * string) { * msg += "!"
}
// Variadic Function
func says(msg...string) { // 메소드 오버로딩이 지원되지 않는다?
for _, s: = range msg {
println(s)
}
}
// Function Return
func sum(nums...int) int { // 파라미터 괄호 뒷 부분에 적어준다.
s: = 0
for _,
n: = range nums {
s += n
}
return s
}
// Named Return Parameter
func sums(nums...int)(count int, total int) { // 명시적으로 리턴될 파라미터를 적는다.
for _, n: = range nums {
total += n
}
count = len(nums)
return // return만 적어준다.
}
// Closure
func nextValue() func() int {
i: = 0
return func() int {
i++
return i
}
}
/* Package */
// 패키지를 통해 코드의 모듈화, 코드의 재사용 기능을 제공한다.
// 표준 라이브러리 패키지들은 GOROOT/pkg 안에 존재한다.
// Main 패키지
// - Go Compiler에 의해 특별하게 인식된다.
// - 해당 패키지를 공유 라이브러리가 아닌 실행 프로그램으로 만든다.
// - 그리고 이 main 패키지 안의 main() 함수가 프로그램의 시작점이 된다.
// - 공유 라이브러리로 만들 때에는, main 패키지나 main 함수를 사용하면 안된다.
// 패키지 Scope
// - 패키지 내에는 함수, 구조체, 인터페이스, 메서드 등이 존재하는데,
// - 이들의 이름(Identifier)이 첫문자를 대문자로 시작하면 이는 public으로 사용할 수 있다.
// 패키지 init 함수와 alias
// - init() -> 패키지 실행 시 처음으로 호출되는 함수
// - alias -> 단지 패키지 내부 init()만 실행하려 할 때 import _ "PATH"
/* Java */
interface Drawer {
public void Draw();
}
class Circle implements Drawer {
int r;
Circle(int r) {
this.r = r;
}
public void Draw() {
System.out.println("Circle is Draw : " + r);
}
}
class Rectangle implements Drawer {
int w, h;
Rectangle(int w, int h) {
this.w = w;
this.h = h;
}
public void Draw() {
System.out.println("Rectangle is w=" + w + " h=" + h);
}
}
public class MyMain {
public static void DrawForm(Drawer d) {
d.Draw();
}
public static void main(String[] args) {
Circle myC = new Circle(5);
DrawForm(myC);
Rectangle myR = new Rectangle(4, 5);
DrawForm(myR);
}
}
/* Go */
type Drawer interface {
Draw()
}
type Circle struct {
r int
}
func(c Circle) Draw() {
fmt.Println("Circle is Draw : ", c.r)
}
type Rectangle struct {
w, h int
}
func(r Rectangle) Draw() {
fmt.Println("Rectangle is w=", r.w, " h=", r.h)
}
func DrawForm(d Drawer) {
d.Draw()
}
func main() {
var myC Circle = Circle {
5
}
var myR Rectangle = Rectangle {
3, 4
}
DrawForm(myC)
DrawForm(myR)
}
func data(fileName string) string {
f: = os.Open(fileName)
defer f.Close()
contents: = io.ReadAll(f)
return contents
}
package pattern
import (
"testing"
)
type patternTest struct {
in , out string
}
var patternTests = [] patternTest {
patternTest {"aaaaa", "a"},
patternTest {"ababab", "ab"},
patternTest {"abaaba", "aba"},
patternTest {"c.c.c.", "c."},
patternTest {"abcdefg", "abcdefg"},
}
func TestPatterns(t * testing.T) {
for _, e: = range patternTests {
v: = getPattern(e.in)
if v != e.out {
t.Errorf("getPattern(%s) = %s, but want %s", e.in, v, e.out)
}
}
}