2015년 7월 21일 화요일

정말 간단하게 GO언어를 요약해봤다.

책을 도서관에서 빌려 온 거라 시간이 없기도 했지만
많은 부분은 아는 부분이라 건너 뛴 것도 많다 -_-;

Go언어는 한국어로 튜토리얼이 되어 있다.(/만세/)

튜토리얼로 하나하나 공부하다 보면 Go언을 쉽게 익힐 수 있을 것이다.

그리고 책도 구입해서 한다면 더 좋을 듯 싶다.

추천하는  책은 "가장 빨리 만나는 GO언어" 다.

안드로이드가 오라클과의 소송에서 패배함으로
안드로이드에 쓰인 자바 언어를 go언어로 바꿀지도 모른다는 생각으로 빠르게 함 봤다.

튜토리얼 주소 : http://go-tour-kr.appspot.com/#1

당분간은 JSP 공부 하느라 글을 못 올릴 것 같다.
jsp는 이곳에 게시하기가 애매하다 -_-;;;

GO 언어 기본 문법 - 9

--------------정렬 활용하기------------
func Sort(data Interface)  //데이터를 오름차순으로 정렬
func Reverse(data Interface) Interface //데이터를 내림차순으로 정렬
type IntSlice []int //int 정렬 인터페이스
type Float64Slice []float64 //float64 정렬 인터페이스
type StringSlice []string //string 정렬 인터페이스

----------컨테이너 사용하기------------
Go언어는 기본 자료구조를 패키지로 제공한다.
연결리스트: 각 노드를 한 줄로 연결한 자료구조
힙: 이진 트리를 활용한 자료구조
링: 각 노드가 원형으로 연결되 자료구조

연결 리스트 사용하기 - container/list 패키지
func New() *List   //연결 리스트 생성
func (L *List)PushBack(v interface{}) *Element  //연결 리스트의 맨 뒤에 데이터 추가
func(L *List)Front() *Element  //연결리스트의 맨 앞 데이터를 가져옴
func(L *List)Back() *Element   //연결리스트의 맨 뒤 데이터를 가져옴

힙 사용하기 - container/heap 패키지
func Init(h Interface)  //힙 초기화
func Push(h Interface, x interface{})  //힙에 데이터 추가

링 사용하기 - container/ring 패키지
func New(n int) *Ring  //링 생성
func (r *Ring) Do(f func(interface{}))  //링의 모든 노드 순회
func (r *Ring) Move(n int) *Ring  //링을 회전시킴. 매개 변수로 양수를 넣으면 시계방향, 음을 넣으면 반 시계 반향으로 회전

----------TCP 프로토콜 사용하기------------

서버 작성하기 -net 패키지

func Listen(net, laddr string)(Listener, error) //프로토콜, IP주소, 포트 번호를 설정하여 연결 대기
func(I *TCPListener)Accept() (Conn, error) //클라이언트가 연결되면 TCP 연결
func(I *TCPListener)Close() error //TCP 연결 대기를 닫음
func(c *TCPConn)Read() (b []byte)(int, error) //받은 데이터 읽기
func(c *TCPConn)Write() (b []byte)(int, error) //데이터 보내기
func(c *TCPConn)Close() error  //TCP 연결을 닫음

클라리언트 작성하기 - net 패키지

func Dial(network, address string)(Conn, error) //프로토콜, IP주소, 포트 번호를 설정, 서버에 연결
func(c *TCPConn) Close() error //TCP 연결을 닫음
func(c *TCPConn) Read(b []byte)(int, error) //받은 데이터를 읽음
func(c *TCPConn) Write(b []byte)(int, error) //데이터를 보냄


GO 언어 기본 문법 - 8

-----------파일 쓰기---------------------
func Create(name string)(file *File, err error)  //기존 파일을 열거나 새 파일을 생성
func(f *File)Close() error  //열린 파일을 닫음
func(f *File)Write(b []byte)(n int, err error)  //파일에 값을 씀. 파일에 쓴 데이터의 길이와 에러 값을 리턴

----------파일 읽기---------------------
func Open(name string)(file *File, err error) //파일 열기
func (f *File) Stat()(fi FileInfo, err error)  //파일의 정보를 얻어옴
func (f *File) Read(b []byte) (n int, err error) //파일에서 값을 읽음

----------파일 읽기 쓰기---------------
//파일 플래그, 파일 모드를 지정하여 파일 열기
func OpenFile(name string, flag int, perm FileMode)(file *File, err error)

//파일을 읽거나 쓸 위치로 이동
func (f *File)Seek(offset int64, whence int)(ret int64, err error)

------------압축 사용하기------------------
//io.Reader인터페이스로 io.Reader 인터페이스를 따르는 압축 해제 인스턴스 생성
func NewReader(r io.Reader)(*Reader, error)

//ioWriter 인터페이스로 io.Writer 인터페이스를 따르는 압축 인스턴스 생성
func NewWriter(w io.Writer)*Writer

//io.Reader를 끝까지 읽어서 바이트 슬라이스로 리턴
func ReadAll(r io.Reader)([]byte, error)

---------------암호화 사용하기---------------

(해쉬 알고리즘 사용하기)-crypto/sha512 패키지

func New() hash.Hash   //SHA512 해시 인스턴스 생성
func Sum512(data []byte) [Size]byte  //SHA512 해시를 계산하여 리턴
func (d *digest)Write(p []byte)(nn int, err error)  //해시 인스턴스에 데이터 추가
func(d0 *digest)Sum(in []byte)[]byte //해시 인스턴스에 저장된 데이터의 SHA512해시값 추출

(AES 대칭킹 알고리즘 사용하기)-crypto/aes 패키지

func NewCipher(key []byte)(cipher.Block, error) 대칭키 암호화 블록 생성
func (c *aesCipher)Encrypt(dst, src []byte) 평문을 AES알고리즘으로 암호화
func(c *aesCipher)Decrypt(dst, src []byte) AES 알고리즘으로 암호화된 데이터를 평문으로 복호화

(RSA 공개키 알고리즘 사용하기)-crypto/rsa 패키지

//개인키와 공개키 생성
func GenerateKey(random io.Reader, bits int)(priv *PrivateKey, err error)

//평문을 공개키로 암호화
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte)(out [[]byte, err error)

//암호화된 데이터를 개인키로 복호화
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte)(out []byte, err error)
















GO 언어 기본 문법 - 7

---------인터넷 소스 저장소의 패키지 사용하기-----------
Go 언어는 로컬 있는 패키지도 지원하지만
인터넷 소스 저장소에 올라와 있는 패키지도 사용할 수 있다

import에 패키지 주소만 설정하면 인터넷 저장소의 패키지를 사용가능
import (
   "fmt"
   "github.com/golang/exdample/stringutil"
)

go get 명령을 입력해서 패키지를 받음

----------패키지의 함수, 변수, 상수를 외부에 노출----------
패키지를 외부에서 사용할 수 있게 하려면 첫글자를 대문자로 지정해야 한다

-------------문서화---------------------
패키지, 함수, 변수, 상수 위에 //주석을 작성하면 설명을 문서화 할수 있다

-------------출력 함수----------------
func Print()  //값을 그 자리에서 출력(새 줄로 넘어가지 않음)
func Println() //값을 출력한 뒤 새 줄로 넘어감(개행)
func Printf()  //형식을 지정하여 값을 출력

--------------입력 함수-----------------
func Scan() //콘솔에서 공백, 새 줄로 구분하여 입력을 받음
func Scanln() //콘솔에서 공백으로 구분하여 입력을 받음
func Scanf() //콘솔에서 형식을 지정하여 입력을 받음

---------------문자열 입출력 함수--------------------
func Sprint() string  //값을 그대로 문자열로 만듦
func Sprintln() string //값을 그대로 문자열로 만든 뒤 문자열 끝에 개행 문자 붙임
func Sprintf() string  //형식을 지정하여 문자열을 만듦

func Sscan() string  //공백, 개행문자로 구분된 문자열에서 입력을 받음
func Sscanln() string //공백으로 구분된 문자열에서 입력을 받음
func Sscanf() string  //문자열에서 형식을 지정하여 입력을 받음

----------------파일 입출력 함수-------------------
func Create(name string)(file *File, err error) //기존 파일을 열거나 새 파일을 생성
func Open(name string)(file *File, err error) //기존 파일 열기
func(f *File) Close() error //열린 파일 닫음

--------------------문자열 처리하기------------------------
func Contains(s, substr string)bool   //문자열이 포함되어 있는지 검색
func ContainsAny(s, chars string)bool //특정 문자가 하나라도 포함되어 있는지 검색
func ContainsRune(s string, r rune)bool  //rune 자료형으로 검색
func Count(s, sep string)int   //문자열이 몇 번 나오는지 구함
func HasPrefix(s, prefix string)bool  //문자열이 접두사인지 판단
func HasSuffix(s, suffix string)bool //문자열이 접미사인지 판단
func Index(s, sep string)int  //특정 문자열의 위치를 구함
func IndexAny(s, chars string)int  //가장 먼저 나오는 문자의 위치를 구함
func IndexByte(s string, c byte)int //byte 자료형으로 위치를 구함

------------문자열 변환 함수-------------------------
func Atoi(s string)(i int, err error)   //숫자로 이루어진 문자열을 숫자로 변환
func Itoa(i int)string  //숫자를 문자열을 변환
func FormatBool(b bool)string  //불 값을 문자열로 반환
func FormatFloat(f float64, fmt byte, prec, bitSize int)string //실수를 문자열로 변환
func FormatInt(i int64, base int)string  //부호 있는 정수를 문자열로 변환
func FormatUint(i uint64, base int)string  //부호 없는 정수를 문자열로 변환












2015년 7월 20일 월요일

GO 언어 기본 문법 - 6

----------고루틴 사용하기-----------
고루틴은 함수를 동시에 실행시키는 기능이다
다른 언어의 스레드 생성보다 문법이 간단하고, 스레드 보다 리소스를 적게 사용한다

함수 호출 시에 go 키워드를 붙이면 해당 함수는 고루틴으로 실행된다.

예제)
package main

import "fmt"

func hello() {
   fmt.Println("Hello, world!")
}

func main() {
   go hello           //함수를 고루틴으로 실행
   fmt.Scanln()       //main 함수가 종료되지 않도록 대기
}

------------멀티코어 활용하기-------------
GO 언어는 CPU 코어를  한 개만 사용하도록 설정되어 있다.
다음은 시스템의 모든 CPU 코어를 사용하는 방법이다.

package main

import (
   "fmt"
   "runtime"
)

func main() {
     //CPU 개수를 구한 뒤 사용할 최대 CPU 개수 설정
   runtime.GOMAXPROCS(runtime.NumCPU()) 
   fmt.Println(runtime.GOMAXPROCS(0))  //설정 값 출력
   s := "Hello, world!"

   for i:=0; i<100; i++ {
       go func(n int) {  //익명 함수를 고루틴으로 실행
          fmt.Println(s, n)
       }(i)
   }

   fmt.Scanln()  //main 함수가 종료되지 않도록 대기
}

-----------채널 사용하기-------------
채널은 고루틴끼리 데이터를 주고 받고, 실행 흐름을 제어하는 기능
make(chan 자료형)

예제)
package main

import "fmt"

func sum(a int, b int, c int) {
   c <- a+b   //채널에 a와 b의 합을 보냄
}

func main() {
   c := make(chan int)  //int 형 채널 생성
   go sum(1, 2, c)        //sum을 고루틴으로 실행한 뒤 채널을 매개변수로 넘겨줌
   n := <-c                //채널에서 값을 꺼낸 뒤 n에 대입
   fmt.Println(n)          //3
}

채널을 사용하기 전에는 반드시 make 함수로 공간을 할당
채널을 매개변수로 받는 함수는 반드시 go키워드를 사용하여 고루틴을 실행해야 한다

함수에서 채널을 매개변수로 받을 때는
변수명 chan 자료형 
형식으로 한다

채널에 값을 보낼 때
채널 <- 값

채널에서 값을 가져올 때
<- 채널

채널 버퍼링
make(chan 자료형, 버퍼개수)

채널에 버퍼를 1개이상 설정하면 비동기 채널이 생성된다.
비동기 채널은 보내는 쪽에서 버퍼가 가득 차면 실행을 멈추고 대기하며
받는 쪽에서는 버퍼에 값이 없으면 대기한다.

Go언어는 여러 채널을 손쉽게 사용할 수 있도록 select 분기문을 제공
select {case <-채널:코드}

select {
case <-채널1:
  //채널1에 값이 들어왔을 때 실행할 코드를 작성
case <-채널2:
  //채널2에 값이 들어왔을 때 실행할 코드를 작성
default:
  //모든 case의 채널에 값이 들어오지 않았을 때 실행할 코드를 작성
}


GO 언어 기본 문법 - 5

--------인터페이스----------

type 인터페이스명 interface {}

인터페이스는 메서드의 집합이다. 단, 메서드 자체를 구현하지는 않는다.
인터페이스 선언하는 방법은 변수 선언법과 같다.

type 인터페이스명 interface {
    메서드1() 리턴값_자료명
    메서드2()       //리턴값이 없을 때
}
주의할 점은 메서드를 ,로 구분하지 않는다는 것이다.

예제)
package main

import (
"fmt"
"math"
)
//인터페이스 선언
type Abser interface {
Abs() float64
}

func main() {
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}

a = f  // a MyFloat implements Abser
a = &v // a *Vertex implements Abser

// In the following line, v is a Vertex (not *Vertex)
// and does NOT implement Abser.
a = v

fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}

type Vertex struct {
X, Y float64
}

func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

GO 언어 기본 문법 - 4

----------포인터 사용하기-----------
var 변수명 *자료형

var numPtr *int //포인터형 변수를 선언하면 nil로 초기화 됨
fmt.Println(numPtr) //nil

Go 언어는 NULL 값을 nil로 사용함.
Go 언어는 메모리 주소를 직접 대입하거나 포인터 연산을 허용하지 않는다.
빈 포인터형 변수는 new 함수로 메모리로 할당해야 함

포인터_변수 = new(자료형)

var numPtr *int = new(int)
fmt.Println(numPtr) //메모리 주소 출력

*포인터_변수명 - 역참조

var numPtr *int = new(int)   //new 함수로 공간 할당
*numPtr = 1                     //역참조로 포인터형 변수에 값을 대입
fmt.Println(*numPtr)           //1 포인터형 변수에서 값을 가져오기

&변수명 - 해당 변수의 메모리 주소

var num int = 1
var numPtr *int = &num  //참조로 num변수의 메모리 주소를 구하여
                                  //numPtr 포인터 변수에 대입
fmt.Println(numPtr)          //numPtr 포인터 변수에 저장된 메모리 주소
fmt.Println(&num)           //참조로 num변수의 메모리 주소를 구함

-------------구조체 사용하기-----------------
구조체 - 여러 변수를 담을 수 있는 구조체

type 구조체명 struct {}

{} 블록 안에는 구조체의 필드 목록을 정의함
type Rectangle struct {
     width int
     height int
}

-----------구조체에 메서드 연결하기-------------
Go언어에는 클래스가 없는 대신 구조체에 메서드를 연결할 수 있다

func(리시버명 *구조체_타입) 함수명() 리턴값_자료형 {}

type Rectangle struct {
     width int
     height int
}
func (rect *Rectangle) area() int {
     return rect.widthrect.height
}
func main() {
      rect := Rectangle{10, 20}
      fmt.Println(rect.area()) //결과값 : 200
}

------------포인터 방식, 일반 구조체 방식-----------
//포인터 방식
func (rect *Rectangle) scaleA(factor int) { //포인터라 원래의 값이 변경 됨
    rect.width = rect.width * factor
    rect.height = rect.height * factor
}

//일반 구조체 방식
func (rect Rectangle) scaleB(factor int) {  //값이 복사되어서 원래의 값에는 영향 x
    rect.width = rect.width * factor
    rect.height = rect.height * factor
}

func main() {
   rect1 := Rectangle{30, 30}
   rect1.scaleA(10)
   fmt.Println(rect1) //{300, 300} : rect1에 바뀐 값이 들어감
 
   rect2 := Rectangle{30, 30}
   rect2.scaleB(10)
   fmt.Println(rect2) //{30, 30} : rect2는 값이 바뀌지 않음

}








GO 언어 기본 문법 - 3

------------함수---------------
함수의 중괄호
함수의 여는 중괄호를 다음 줄에 작성하면 에러
func hello()   //에러
{
   //어쩌구
}

익명함수
함수에는 이름이 없는 함수를 익명 함수라고 한다. 익명함수는 정의한 뒤 바로 호출 가능

func() {            //함수에 이름이 없음
   fmt.Println("Hello, world!")
}()

func(s string) {  //익명 함수를 정의한 후
    fmt.Println(s)
}("Hello, world!")  //바로 호출

r:= func(a int, b int) int { //익명 함수를 정의한 뒤
   return a + b
}(1,2)  //바로 호출하여 리턴값을 변수 r에 저장

클로저
클로저는 함수 안에서 함수를 선언 및 정의할 수 있고,
바깥쪽 함수에 선언된 변수에도 접근할 수 있는 함수를 말한다.
또한 클로저를 사용하면 지역변수가 소멸되지 않고,
나중에 함수를 호출할 때마다 계속 가져다 쓸수 있다.
즉, 클로저는 함수가 선언될 때의 환경을 계속 유지하여 함수의 변수에 저장할 수 있다

func calc() func(x int) int {
   a,b := 3,5   //지역 변수는 함수가 끝나면 소멸되지만
   return func(x int) int {
       return a*x + b //클로저이므로 함수를 호출 할 때마다 변수 a,b의 값을 사용
   }
}
func main() {
   f := calc() //calc 함수를 실행하여 리턴 값으로 나온 클로저를 변수에 저장
   fmt.Println(f(1))  //8
   fmt.Println(f(2))  //11
   fmt.Println(f(3))  //14
   fmt.Println(f(4))  //17
   fmt.Println(f(5))  //20
}

recover
recover 함수를 사용하면 패닉이 발생했을 때 프로그램이 바로 종료되지 않고 예외 처리를 할 수 있음

func f() {
   defer func() {               //recover 함수는 지연 호출로 사용해야 함
      s := recover()           //패닉이 발생해도 프로그램을 종료하지 않음
      fmt.Println(s)            //panic 함수에서 설정한 에러 메세지를 받아옴
   }()
   panic("Error!!!")
}
func main() {
    f()
    fmt.Println("Hello, world!")  //패닉이 발생했지만 계속 실행됨
}

GO 언어 기본 문법 - 2

--------for 반복문----------

Go 언어는 반복문이 for만 있다.

for 초기값; 조건식; 변화식 {
     //여기에 반복할 코드를 작성한다.
}

if문과 마찬가지로 조건식에 ()를 사용하지 않는다.
역시 {}를 생략해서도 안된다.

for 키워드에 조건식만 설정하면 while 문과 같다.
for 조건식 {
 //여기에 반복할 코드를 작성
 //변화식도 함께 작성
}

for 문에 조건식을 설정하지 않으면 무한루프다

반복문에서 변수 여러개 사용하기

//i가 10 보다 작을 때까지 반복하면서 i는 1씩 증가, j는 2씩 증가
for i,j := 0, 0; i<10; i,j = i+1, j+2 {
   fmt.Println(i, j)
}

----switch 분기문-----

switch 변수 {case 값: 코드}

switch 변수 {
case 값1:
     //값 1일 때 실행할 코드를 작성
case 값2:
     //값 2일 때 실행할 코드를 작성
case 값3:
     //값 3일 때 실행할 코드를 작성
default:
    //모든 case에 해당하지 않을 때 실행할 코드 작성
}

----------배열----------

var 배열명 [길이]자료형

var a [5]int    //int형이며 길이가 5인 배열 선언
a[2] = 7        //배열의 세번째 요소에 7 대입
fmt.Println(a)  //[00700]

배열을 순회할 때는 for반복문에서 range 키워드를 사용
a:=[5]int{11,22,33,44,55}
for i, value := range a {  //i에는 인덱스, value에는 배열 요소의 값이 들어감
   fmt.Println(i, value)
}

슬라이스는 길이가 고정되어 있지 않으며 동적으로 크기가 늘어난다.
a := []int{1,2,3}
var b []int //슬라이스로 선언
b = a
b[0] = 9
fmt.Println(a) //[9,2,3]
fmt.Println(b) //[9,2,3]

------------맵----------------
맵은 키-값 형태로 자료를 저장하며 레퍼런스 타입이다
aaa := make(map[string]float32) //키는 string, 값은 float32인 맵 생성 및 공간 할당
aaa["ccc"] = 222 //맵[키]=값

range로 맵 순회
맵을 순회할 때는 for반복문에서 range 키워드를 사용

//반복문이 실행될 때마다 키와 값이 자동으로 변수에 들어감
for key, value := range aaa {
     fmt.Println(key, value)
}


GO 언어 기본 문법 - 1

1) 중괄호는 반드시 구문의 맨 뒤에서 시작
func main() {
    var num int = 1
}

2) 변수 짧은  선언
변수명 := 초기값 형식으로 var 키워드를 사용하지 않고 변수를 선언
age := 10
name := "Maria"

3)병렬 할당
var x, y int
var age int

x, y, age=10, 20, 5

4)go 언어는 변수에 문자열을 저장한 뒤 내용을 수정할 수 없다.

5)문장의 끝에 세미콜론(;)을 넣을 필요 없다.

6) 변수 할당은 자료명이 뒤에 들어간다.

var num int = 1 //int 형 num변수에 1을 할당한다.

7) go언어는 문자와 문자열을 유니코드 UTF-8로 지정한다.

8) 패키지 선언 방법

(1) 단일 선언법
import "fmt"

(2) 여러개 패키지 선언
import (
   "fmt"
   "runtime"
)

(3) 전역 패키지로 사용 .(점)을 사용하면 전역 패키지가 된다.
import . "fmt"

(4) 패키지 별칭 사용
import f "fmt" //fmt를 f로 가져옴

(5) 사용하지 않는 패키지(go언어는 사용하지 않는 패키지 선언시 컴파일 에러)
import _ "fmt" //컴파일 에러 발생 안함

9) if 조건문

if 조건식 {}

if 조건식을 사용할 때 ()를 사용하지 앟으며 조건문을 시작하는 줄에서 {가 시작된다.
또한, 한줄 if 문이라도 {} 를 생략하지 않아야 한다.

예제)
i := 6
if i >= 5 {
   fmt.Println("5이상")
}else if i>=5 && i<10 {
   fmt.Println("5이상, 10미만")
}else if i>=0 && i <5 {
   fmt.Println("0 이상, 5미만")
}


Go언어 공부를 해보려고 한다.

Go 언어는 구글에서 만든 언어다.
이 언어를 공부하려는 이유는....
구글이 최근 오라클에게 소송에서 졌기 때문이다 ;;;
안드로이드에 쓰인 자바를 무단으로 썼다고 오라클이 소송을 건듯 하다;;;
안드로이드가 go언어로 바뀌지 않을까 하는 마음에 대충 훓어볼려고 한다.
절대로 도서관에서 책을 빌렸기 때문이 아니다....;;

go언어는 설치를 해야 쓸수 있는 언어다.

go 언어 다운받기 : https://golang.org/dl/

설치후에는 IDE를 다운 받아 사용하는 것이 편하다.

LiteIDE 다운 받기 : http://sourceforge.net/projects/liteide/files/
LiteIDE 다운 받기 : https://github.com/visualfc/liteide

Go 언어는 한국어로(!) 튜토리얼을 사용할 수 있다.

Go 언어를 설치하면 GoDocServer 를 실행시키면 튜토리얼을 사용할 수 있다.

또는 튜토리얼 사이트 : http://go-tour-kr.appspot.com/#1

책은 이 책을 추천한다.

"가장 빨리 만나는 Go 언어"

http://www.yes24.com/24/goods/18077092?scode=032&OzSrank=1

다음부터는 간단하게 go언어의 특징만 요약해볼꺼다~