// 함수에 값을 전달했고 함수에서 변수를 변경했지만 원래 변수값은 변하지 않았다.
package main
import (
"fmt"
)
func main() {
// Pass By Value
str := "hello"
fmt.Println("Before func:", str) // 함수에 넘기기 전 변수값
PassByValue("Func processed:", str) // 넘긴 이후 함수에서 변경
fmt.Println("After func:", str) // 함수에서 변경해도 원 변수값은 변하지 않음
}
func PassByValue(msg string, text string) {
text = "hi"
msg = msg + " " + text + " " + "world"
fmt.Println(msg)
}
// 결과
// Before func: hello
// Func processed: hi world
// After func: hello
// 함수에 값을 전달했고 함수 안에서 전달한 변수를 변경했다.
package main
import (
"fmt"
)
func main() {
// Pass by reference
str := "hello"
fmt.Println("Before func:", str) // 함수에 넘기기 전 변수값
PassByReference("Func processed string:", &str) // 넘긴 이후 변경된 문자열 출력
fmt.Println("After func:", str) // 넘긴 변수의 값도 변경되었다.
}
func PassByReference(msg string, text *string) {
*text = "hi"
msg = msg + " " + *text + " " + "world"
fmt.Println(msg)
}
// 결과
// Before func: hello
// Func processed string: hi world
// After func: hi
package main
import (
"fmt"
)
func main() {
var sum1, sum2 int
sum1 = VariadicFunc(1, 2, 3) // 3개의 파라미터도 받는다.
fmt.Println("sum1:", sum1)
sum2 = VariadicFunc(1, 2) // 2개의 파라미터도 받는다.
fmt.Println("sum2:", sum2)
fmt.Println(" ")
var (
one = 1
two = 2
three = 3
)
VariadicFuncByReference(&one, &two, &three) // 변수의 주소를 넘김
fmt.Println("one:", one) // 함수에 넘긴 원본 변수값이 변함
fmt.Println("two:", two)
fmt.Println("three:", three)
}
func VariadicFunc(nums ...int) int {
var total int
for _, n := range nums {
total += n
}
return total
}
func VariadicFuncByReference(nums ...*int) { // 가변인자로 주소를 받음
for _, n := range nums {
*n -= 1 // 주소의 변수값을 읽어 처리
}
}
// 결과
// sum1: 6
// sum2: 3
//
// one: 0
// two: 1
// three: 2
1. 함수 복수값 리턴
package main
import (
"fmt"
)
func main() {
count, total := sum(1, 2, 3, 4, 5)
fmt.Println("count:", count, "total:", total)
}
func sum(nums ...int) (int, int) {
count := 0
sum := 0
for _, n := range nums {
sum += n
count++
}
return count, sum
}
// 결과
//
// count: 5 total: 15
package main
import (
"fmt"
)
func main() {
count, total := sum(1, 2, 3, 4, 5)
fmt.Println("count:", count, "total:", total)
count2, total2 := named_return_sum(1, 2, 3)
fmt.Println("count2:", count2, "total2:", total2)
}
func sum(nums ...int) (int, int) {
count := 0
sum := 0
for _, n := range nums {
sum += n
count++
}
return count, sum
}
func named_return_sum(nums ...int) (count int, sum int) { // 리턴 파라미터 명과 타입을 명시
for _, n := range nums {
sum += n
count++
}
return // 명시한 리턴 파라미터를 반환
}
// 결과
//
// count: 5 total: 15
// count2: 3 total2: 6
package main
import (
"fmt"
)
// 익명함수 사용, 가변인자 사용, 리턴 파라미터 명과 타입을 여러 개 명시
func main() {
anonymous_sum := func(nums ...int) (count int, sum int) {
for _, n := range nums {
sum += n
count++
}
return
}
count, sum := anonymous_sum(1, 2, 3)
fmt.Println("count:", count, "sum:", sum)
}
// 결과
//
// count: 3 sum: 6
package main
import (
"fmt"
)
func main() {
p := fmt.Println
anon_sum := func(x int, y int) int {
return x + y
}
// 익명함수를 변수에 넣어 전달
c1 := calc(anon_sum, 1, 2)
p("sum of c1:", c1)
// 다른 함수의 파라미터로 함수 자체를 전달
c2 := calc(func(x int, y int) int { return x + y }, 1, 2)
p("sum of c2:", c2)
}
func calc(f func(int, int) int, x int, y int) int {
return f(x, y)
}
// 결과
//
// sum of c1: 3
// sum of c2: 3
package main
import (
"fmt"
)
func main() {
f := func(x int, y int) int {
return x + y
}
r1 := calc(f, 1, 2)
fmt.Println(r1)
}
// 함수 원형을 정의
type sum func(int, int) int
func calc(f sum, x int, y int) (ret int) {
ret = f(x, y)
return
}
// 결과
//
// 3
package main
import (
"fmt"
)
func main() {
c := addString() // 함수를 변수에 저장
fmt.Println(c("hello"))
fmt.Println(c("world"))
fmt.Println(c("friend"))
}
// addString() 함수의 리턴이 익명함수
// 리턴된 익명함수의 리턴값은 string
func addString() func(text string) string {
strs := ""
// 익명함수를 리턴하지만 그 익명함수가 다시 지역변수를 리턴
return func(text string) string {
strs = strs + "|" + text
return strs
}
}
// 결과
//
// |hello
// |hello|world
// |hello|world|friend
package main
import (
"fmt"
)
func main() {
c := count{} // 구조체를 변수에 할당
fmt.Println("Initial counter:", c.counter)
addCounter(&c) // 함수에 구조체 주소 넘김
addCounter(&c) // 함수 안에서 구조체 값 증가
fmt.Println("After func counter:", c.counter) // 결국
}
func addCounter(c *count) {
c.counter++
}
type count struct {
counter int
}
// 결과
//
// Initial counter: 0
// After func counter: 2
package main
import (
"fmt"
)
func main() {
e1 := &employees{
name: "mike", age: 30, country: "USA",
}
e1.ageUp()
fmt.Println(e1.age)
e1.ageDown()
fmt.Println(e1.age)
}
type employees struct {
name string
age int
country string
}
func (e *employees) ageUp() {
e.age++
}
func (e *employees) ageDown() {
e.age--
}
// 결과
//
// 31
// 30
Method | Function |
It contain receiver. | It does not contain receiver. |
It can accept both pointer and value. | It cannot accept both pointer and value. |
Methods of the same name but different types can be defined in the program. | Functions of the same name but different type are not allowed to define in the program. |
It cannot be used as a first-order object. | It can be used as first-order objects and can be passed. |
package main
import (
"fmt"
)
type myint int
func (i1 myint) add(i2 myint) (out myint) {
out = i1 + i2
return
}
func main() {
v1 := myint(1)
v2 := myint(2)
ret := v1.add(v2)
fmt.Println("result:", ret)
}
// 결과
//
// result: 3
package main
import (
"fmt"
)
func main() {
s := sum(1, 2, 3, 4, 5)
fmt.Println("The sum is", *s)
}
func sum(values ...int) *int {
fmt.Println(values)
ret := 0
for _, v := range values {
ret += v
}
return &ret
}
// 결과
//
// [1 2 3 4 5]
// The sum is 15
package main
import (
"fmt"
)
func main() {
d, err := divide(5.0, 0.0)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(d)
}
func divide(a, b float64) (float64, error) {
if b == 0.0 {
return 0.0, fmt.Errorf("Cannot divide by zero")
}
return a / b, nil
}
// 결과
//
// Cannot divide by zero
package main
import (
"fmt"
)
func main() {
g := greeter{
greeting: "Hello",
name: "Go",
}
g.greet()
}
type greeter struct {
greeting string
name string
}
// syntatic sugar
// func (g *greeter) greet() {
func (g greeter) greet() {
fmt.Println(g.greeting, g.name)
g.name = ""
}
// 결과
//
// Hello Go
Parameters
- Comma delimited list of variables and types
- func foo(bar string, baz int)
- Parameters of same type list type once
- func foo(bar, baz int)
- When pointers are passed in, the function can change the value in the caller
- This is always true for data of slices and maps
- Use variadic parameters to send list of same types in
- Must be last parameter
- Received as a slice
- func foo(bar string, baz ...int)
- Retuen values
- Single return vales just list type
- func foo() int
- Multiple return value list types surrounded by parentheses
- func foo() (int, error)
- The (result type, error) paradign is a very common idom.
- Can use names return values
- Initializes returned variable
- Return using return keyword on its own
- Can return addressed of local variables
- Automatically promoted from local memory (stack) to shared memory (heap)
- Anonymous functions
- Functions don't have names if they are
== func() {
...
}()
- Assigned to a variable or passed as an argument to a function
== a := func() {
...
}
a()
- Functions as types
- Can assign functions to variables or use as argument and return values in functions
== var f func(string, string, int) (int, error)
- Methods
=== Function that executes in context of a type
- Format
== func (g greeter) greet() {
...
}
- Receiver can be value or pointer
== Value receiver gets copy of type
== Pointer receiver gets pointer to type
package main
import (
"fmt"
)
func main() {
sum := adder()
for i := 0; i < 10; i++ {
fmt.Println(sum(i))
}
}
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
// 결과
//
// 0
// 1
// 3
// 6
// 10
// 15
// 21
// 28
// 36
// 45
package main
import (
"fmt"
)
func main() {
cycleNames([]string{"cloud", "tifa", "barret"}, sayGreeting)
}
func sayGreeting(name string) {
fmt.Printf("Good morning %v\n", name)
}
func sayBye(name string) {
fmt.Printf("Goodbye %v\n", name)
}
func cycleNames(name []string, f func(string)) {
for _, v := range name {
f(v)
}
}
// 결과
//
// Good morning cloud
// Good morning tifa
// Good morning barret
package main
import (
"fmt"
"strings"
)
func main() {
fn1, sn1 := getInitials("tifa lockhart")
fmt.Println(fn1, sn1)
fn2, sn2 := getInitials("cloud strife")
fmt.Println(fn2, sn2)
fn3, sn3 := getInitials("barret")
fmt.Println(fn3, sn3)
}
func getInitials(str string) (string, string) {
s := strings.ToUpper(str)
strs := strings.Split(s, " ")
var initials []string
for _, v := range strs {
initials = append(initials, v[:1])
}
if len(initials) > 1 {
return initials[0], initials[1]
}
return initials[0], "_"
}
// 결과
//
// T L
// C S
// B _
package main
import (
"fmt"
)
type bill struct {
name string
items map[string]float64
tip float64
}
// format the bill
func (b *bill) format() string {
fs := "Bill breakdown: \n"
var total float64 = 0
// list items
for k, v := range b.items {
fs += fmt.Sprintf("%-25v ...$%v \n", k+":", v)
total += v
}
// add tip
fs += fmt.Sprintf("%-25v ...$%v \n", "tip:", b.tip)
// total
fs += fmt.Sprintf("%-25v ...$%0.2f", "total:", total+b.tip)
return fs
}
func main() {
myBill := newBill("mario's bill")
myBill.addItem("onion soup", 4.50)
myBill.addItem("veg pie", 8.95)
myBill.addItem("toffee pudding", 4.9)
myBill.addItem("coffee", 3.25)
myBill.updateTip(10)
fmt.Println(myBill.format())
}
// make new bills
func newBill(name string) bill {
b := bill{
name: name,
items: map[string]float64{"pie": 5.99, "cake": 3.99},
tip: 0,
}
return b
}
// update tip
func (b *bill) updateTip(tip float64) {
b.tip = tip
}
// add an item to the bill
func (b *bill) addItem(name string, price float64) {
b.items[name] = price
}
// 결과
//
// Bill breakdown:
// onion soup: ...$4.5
// veg pie: ...$8.95
// toffee pudding: ...$4.9
// coffee: ...$3.25
// pie: ...$5.99
// cake: ...$3.99
// tip: ...$10
// total: ...$41.58
댓글 영역