zoukankan      html  css  js  c++  java
  • golang内置数据类型作为函数参数

    • 先上结论

      golang的所有内置类型作为函数参数传递都是传值的方式(没有传递引用一说),需要注意的是:数组、slice和map作为函数参数时也是传值,但是如果对结构内元素进行的修改,修改的是原数据。如果是对其进行整体赋值,则不会修改原数据,相当于拷贝出一个新的临时变量。要想无论什么情况都修改原数据,可以通过传递指针参数实现。

    • 来段实例代码
      1 package main
      2 
      3 import (
      4     "bytes"
      5     "fmt"
      6     "strings"
      7 )
      8 
      9 func f_1(a int) {
     10     a = 2
     11 }
     12 
     13 func f_1_1(a *int) {
     14     *a = 2
     15 }
     16 
     17 func f_2(s string) {
     18     s = "cba"
     19 }
     20 
     21 func f_2_1(s *string) {
     22     *s = "cba"
     23 }
     24 
     25 func f_3(v []string) {
     26     v[0] = "haha"
     27 }
     28 
     29 func f_3_1(v []string) {
     30     v = nil
     31 }
     32 
     33 func f_3_2(v *[]string) {
     34     *v = nil
     35 }
     36 
     37 func f_4(m map[int]int) {
     38     m[1] = 3
     39     m[3] = 1
     40 }
     41 
     42 func f_4_1(m map[int]int) {
     43     m = nil
     44 }
     45 
     46 func f_4_2(m *map[int]int) {
     47     *m = nil
     48 }
     49 
     50 func f_5(b []byte) {
     51     b[0] = 0x40
     52 }
     53 
     54 func f_5_1(b []byte) {
     55     b = bytes.Replace(b, []byte("1"), []byte("a"), -1)
     56 }
     57 
     58 func f_5_2(b *[]byte) {
     59     *b = bytes.Replace(*b, []byte("1"), []byte("a"), -1)
     60 }
     61 
     62 type why struct {
     63     s []string
     64 }
     65 
     66 func (ss why) SetV(s []string) {
     67     ss.s = s
     68 }
     69 
     70 func (ss *why) SetP(s []string) {
     71     ss.s = s
     72 }
     73 
     74 func (ss why) String() string {
     75     return strings.Join(ss.s, ",")
     76 }
     77 
     78 func main() {
     79     a := 1
     80     s := "abc"
     81     v := []string{"sd", "aa"}
     82     m := map[int]int{1: 1, 2: 2, 3: 3}
     83     f_1(a)
     84     f_2(s)
     85     f_3(v)
     86     f_4(m)
     87     fmt.Printf("%d,%s,%v,%v
    ", a, s, v, m)
     88     f_3_1(v)
     89     f_4_1(m)
     90     fmt.Printf("%d,%s,%v,%v
    ", a, s, v, m)
     91     f_1_1(&a)
     92     f_2_1(&s)
     93     f_3_2(&v)
     94     f_4_2(&m)
     95     fmt.Printf("%d,%s,%v,%v
    ", a, s, v, m)
     96     b := []byte("12145178")
     97     f_5(b)
     98     fmt.Printf("%s
    ", b)
     99     f_5_1(b)
    100     fmt.Printf("%s
    ", b)
    101     f_5_2(&b)
    102     fmt.Printf("%s
    ", b)
    103     ss := &why{}
    104     ss.SetV([]string{"abc", "efg"})
    105     fmt.Println(ss)
    106     ss.SetP([]string{"abc", "efg"})
    107     fmt.Println(ss)
    108 }

    输出如下

     1 1,abc,[haha aa],map[1:3 2:2 3:1] slice和map值传递是可以修改原数据的,但基本数据类型不行
     2 1,abc,[haha aa],map[1:3 2:2 3:1] 整体赋值不会修改原数据,值得注意的是map是无序的
     3 2,cba,[],map[] 传递指针始终会修改原数据
     4 @2145178 同上
     5 @2145178 使用bytes.Replace实际上还是赋值,所以不会修改原数据
     6 @2a45a78 使用指针传参就可以了
     7          类的成员函数定义为传值的方式,不会修改原数据(原数据为空)
     8 abc,efg  类的成员函数定义为传指针的方式,可以修改原成员变量
     9 
    10 成功: 进程退出代码 0.

    现在弄明白了吗~

  • 相关阅读:
    set<char*>s
    sscanf()函数。
    C语言函数sscanf()的用法 (转载
    zjut 1179 平均数
    C++数据间隔
    C++ 保留小数
    c++ 保留小数
    c语言 保留两位小数
    c++ 如何实现保留小数并 且 不进行四舍五入
    uva-657-搜索
  • 原文地址:https://www.cnblogs.com/borey/p/5622820.html
Copyright © 2011-2022 走看看