如何在core / types / block.go中理解'rlpHash'方法

the code:

func rlpHash(x interface{}) (h common.Hash) {
    hw := sha3.NewKeccak256()
    rlp.Encode(hw, x)
    hw.Sum(h[:0])
    return h
}

If useful:

func (d *state) Sum(in []byte) []byte {
    dup := d.clone()
    hash := make([]byte, dup.outputLen)
    dup.Read(hash)
    return append(in, hash...)
}

Full code context see here.

How to understand 'h' here?

Shouldn't assign a value to h first?

'h[:0]' means a zero-value byte?

What a 'h' returned exactly?

'hw.Sum(h[:0])' has a return value ,just ignored?

Confused...

Some thoughts...hope it help:

h[:0] -> create an empty slice from h...but it still refer to the same underlying array.

The slice then is being passed to the method hw.Sum(h[:0]) Note that when you passed a slice to a method, the target method can change value of the slice (because slice is a reference type, search relect.SliceHeader to see why)

If you look at the method Sum. It's actually change the value of the slice h by below line of code:

return append(in, hash...)

So, the return statement do 2 jobs:

  1. Change the content of the slice in (h in our case)
  2. Return the slice h

They are using named return h, hence for me it's make the code a little bit difficult to read.

By the way, the below code make it clear how the slice work (sorry if not):

package main

import (
    "fmt"
)

func Sum(in []byte) []byte {
    return append(in, []byte{'a','b'}...)
}

func main() {
    h := [4]byte{}
    Sum(h[:0])
    fmt.Printf("%s
", h) //should print 'ab'
}