使用var关键字初始化切片

Nowadays I am learning Golang and don't understand a situation how Golang behaves.

Here it is a declaration and initialization of a slice by short hand:

ilist := []int{1, 2, 3}  //it works

on the other hand if I try to declare and initialize it with the var keyword, it gives an error:

var ilist [] int = {1, 2, 3, 4, 5}  //error

If I initialize just a variable (not a slice) it works fine:

var i int = 5 // works fine

Why does Golang behave like this, is there any specific reason?

i give the all information to create composite literal

That's the thing: you did not give all the required information to create a composite literal. Check out the Spec: Composite literals section to see what is required.

This literal:

{1, 2, 3, 4, 5}

This literal misses the type information. It could be a part of an []int{} literal, it could be a part of a []float32{} literal, it could even be a part of a struct literal, where the struct type has int fields (e.g. type Ints struct{a,b,c,d,e int}).

Yes, in this variable declaration

var ilist [] int = {1, 2, 3, 4, 5}  //error

Only []int{} literal makes sense, but that is not how Go works. Just because there is only a single type that would make this line valid, it doesn't mean you can omit it.

Note that however you may omit the type from the declaration if it can be inferred from the initialization expression, so both of these forms are valid:

var ilist1 []int = []int{1, 2, 3, 4, 5}

var ilist2 = []int{1, 2, 3, 4, 5}

But the type of {1, 2, 3, 4, 5} would be ambiguous (if it would be valid).

Also note that if you're specifying a composite literal for a type like [][]int, you may omit the type from the (sub)literals of the elements, because it is known from the type of the composite literal, so this is also valid:

var iilist = [][]int{
    {1, 2, 3},
    {4, 5, 6},
}

Same goes for map literals, this is valid (was added in Go 1.5):

var imap = map[int][]int{
    1: {1, 2, 3},
    2: {4, 5, 6},
}

Try these on the Go Playground.

In go, different names mean different types. So when you define a variable, you must specify its type. That means, you need make sure that your assignment is a concrete type. "{}" can be more than one type, so the compilier can not find ilist type. BTW, some friends rise a discussion about Proposal: Alias declarations for Go