

main関数で

[code]

    var count int
    var listcount []int
    
[/code]

を宣言して  
以下の `replaceFileContents` 関数の中身の最後にインクリメントで

[code]

    count++
    listcount = append(listcount, count)
    
[/code]

を書いて実行したのですが、

[code]

    fmt.Println("置換したファイル合計数は"+len(listcount))
    
[/code]

で、`0`が表示されてしまいます。値の受け渡しがうまくできてないのでしょうか？エラーは出ていないのですが、どこが問題なのか原因がわかりにくく。

[code]

    func replaceFileContents(path string, before, after []byte, count int, listcount []int) error {
        read, err := ioutil.ReadFile(path)
        if bytes.Contains(read, before) {
            newContents := bytes.Replace(read, before, after, -1)
            err = ioutil.WriteFile(path, newContents, os.ModePerm)
            if err != nil {
                return err
            }
        }
        fmt.Println("置換したファイル:" + path)
        count++
        listcount = append(listcount, count)
        return nil
    }
    
    func main() {
        var count int
        var listcount []int
    
        root := input("ファイルパス")
        before := []byte(input("置換前文字列"))
        after := []byte(input("置換後文字列"))
    
        err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
            if err != nil {
                return err
            }
            matched, err := filepath.Match("*log.xml", fi.Name())
            if err != nil {
                panic(err)
            }
    
            if fi.IsDir() || !matched {
                //if fi.IsDir() || filepath.Ext(fi.Name()) != ".xml" {
                return nil
            }
    
            return replaceFileContents(path, before, after, count, listcount)
        })
    
        if err != nil {
            panic(err)
        }
    
        fmt.Println("置換したファイル合計数は"+len(listcount))
    }
    
    
[/code]


CC BY-SA 4.0
2021-05-11T13:14:17.943
75786
2021-05-13T17:34:16.267
2021-05-12T05:31:02.027
19110
45221
question
go
Go言語におけるインクリメントについて


Goの値渡し／ポインタ（参照）渡しに関する理解が不足しています。  
以下の簡単な比較コードを試して、違いを確かめてください。

[code]

    package main
    import "fmt"
    
    func addToList1(list []int, x int) {
        list = append(list, x)
    }
    
    func addToList2(list *[]int, x int) {
        *list = append(*list, x)
    }
    
    func main() {
        {
            var list1 []int
            for i := 0; i < 10; i++ {
                addToList1(list1, i)
            }
            fmt.Printf("Count = %d\n", len(list1))
        }
        {
            var list2 []int
            for i := 0; i < 10; i++ {
                addToList2(&list2, i)
            }
            fmt.Printf("Count = %d\n", len(list2))
        }
    }
    
[/code]

`addToList1()`関数は値渡しなので、仮引数の`list`は、上記の呼び出し例では`main()`関数内の`list1`をコピーした別物になります。  
仮引数はローカル変数の一種であり、仮引数に対する変更は実引数に影響を及ぼさず、関数を抜けると捨てられます。  
`addToList2()`関数はポインタ渡しなので、仮引数の`list`は、上記の呼び出し例では`main()`関数内の`list2`のアドレスを保持しています。  
ポインタを`*`演算子でデリファレンスすることで、実体への参照を得ることができ、オブジェクトの読み取りと書き換えが可能となります。

配列のようなサイズの大きいデータ構造は、毎回コピーするとコストが大きいので、読み取りだけであっても基本的にポインタ渡しにします。


CC BY-SA 4.0
2021-05-13T17:25:48.797
75824
2021-05-13T17:34:16.267
2021-05-13T17:34:16.267
15413
15413
75786
answer