本文整理汇总了Golang中github.com/corestoreio/csfw/storage/money.New函数的典型用法代码示例。如果您正苦于以下问题:Golang New函数的具体用法?Golang New怎么用?Golang New使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了New函数的16个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: TestDiv
func TestDiv(t *testing.T) {
tests := []struct {
have1 int64
have2 int64
want int64
}{
{1300, 1300, 10000},
{13, -13, -10000},
{9000, -3000, -30000},
{13, 13, 10000},
{471100, 81500, 57804},
{45628734653, -45628734653, -10000},
{math.MaxInt64, 2, -9223372036854775807},
}
for _, test := range tests {
c := money.New().Set(test.have1)
c = c.Div(money.New().Set(test.have2))
have := c.Raw()
nob, err := c.Number()
assert.NoError(t, err)
if have != test.want {
t.Errorf("\nWant: %d\nHave: %d / %s\nIndex: %v\n", test.want, have, string(nob), test)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:27,代码来源:money_test.go
示例2: Benchmark_MoneyNewGetf
// Benchmark_MoneyNewGetf 2000000 771 ns/op 208 B/op 7 allocs/op => Go 1.4.2
// Benchmark_MoneyNewGetf 3000000 404 ns/op 160 B/op 3 allocs/op => Go 1.5.0
func Benchmark_MoneyNewGetf(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
c := money.New(money.WithPrecision(100)).Setf(-123456.789)
benchmarkMoneyNewGetf = c.Getf()
}
}
开发者ID:joao-parana,项目名称:csfw,代码行数:9,代码来源:money_bm_test.go
示例3: TestSetf
func TestSetf(t *testing.T) {
tests := []struct {
prec int
want int64
havef float64
}{
{0, 13, 13.0000},
{10, 13, 1.30000},
{100, 13, 0.130000},
{1000, 13, 0.013000},
{100, -13, -0.130000},
{0, -45628734653, -45628734653.000000},
{10, -45628734653, -4562873465.300000},
{100, -45628734653, -456287346.530000},
{1000, -45628734653, -45628734.653000},
{100, 256, 2.56},
10: {1234, -45628734653, -4562873.46530000}, // fallback to prec 10000
{100, -45628734655, -456287346.550000},
{100, -45628734611, -456287346.110000},
{100, -45628734699, -456287346.990000},
14: {10000000, 45628734699, 4562.87346989999969082419},
15: {10000000, 45628734655, 4562.87346549999983835733},
}
for i, test := range tests {
c := money.New(money.WithPrecision(test.prec)).Setf(test.havef)
haveR := c.Raw()
if haveR != test.want {
t.Errorf("\nWantI: %d\nHaveI: %d\nIndex: %d\n", test.want, haveR, i)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:32,代码来源:money_test.go
示例4: TestMulf
func TestMulf(t *testing.T) {
tests := []struct {
prec int
have1 int64
have2 float64
want string
}{
{100, 1300, 1300.13, "16,901.690"},
{1000, 18100, 18100.18, "327,613.258"},
{0, 18100, 18100.18, "327,613,258.000"},
{0, 18103, 18.307, "331,412.000"}, // rounds up
{100, 1319, 1488.88, "19,638.330"},
{1000, 1319, 1488.88, "1,963.833"},
{100, 13, -13.13, "-1.710"},
{100, 1300, -1300.01, "-16,900.130"},
{1000, 1300, -1300.01, "-1,690.013"},
{100, 13, 13.0, "1.690"},
{100, 45628734653, -45628734653.0, "-47,780,798,383.280"},
{100, math.MaxInt64, 2.01, "92,233,720,368.530"},
}
for _, test := range tests {
c := money.New(money.WithPrecision(test.prec)).Set(test.have1)
c = c.Mulf(test.have2)
haveB, err := c.Number()
assert.NoError(t, err)
have := string(haveB)
if have != test.want {
t.Errorf("\nWant: %s\nHave: %s\nSign %d\nIndex: %v\n", test.want, have, c.Sign(), test)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:32,代码来源:money_test.go
示例5: TestJSONMarshal
func TestJSONMarshal(t *testing.T) {
// @todo these tests will fail once i18n has been fully implemented. so fix this.
var prefix = `"` + string(i18n.DefaultCurrencySign) + " "
tests := []struct {
prec int
haveI int64
haveEnc money.Encoder
haveValid bool
want string
wantErr error
}{
{100, 123456, money.JSONNumber, true, `1234.56`, nil},
{1000, 123456, money.JSONNumber, true, `123.456`, nil},
{10000, 123456, money.JSONNumber, true, `12.3456`, nil},
{10, 123456, money.JSONNumber, true, `12345.6`, nil},
{100, 123456, money.JSONNumber, false, `null`, nil},
{0, 123456, money.JSONNumber, true, `123456`, nil},
{100, 123456, money.JSONLocale, true, prefix + `1,234.56"`, nil},
{1000, 123456, money.JSONLocale, true, prefix + `123.46"`, nil},
{10000, 123456, money.JSONLocale, true, prefix + `12.35"`, nil},
{10, 123456, money.JSONLocale, true, prefix + `12,345.60"`, nil},
{100, 123456, money.JSONLocale, false, `null`, nil},
{0, 123456, money.JSONLocale, true, prefix + `123,456.00"`, nil},
{100, 123456, money.JSONExtended, true, `[1234.56, "$", "$ 1,234.56"]`, nil},
{1000, 123456, money.JSONExtended, true, `[123.456, "$", "$ 123.46"]`, nil},
{10000, 123456, money.JSONExtended, true, `[12.3456, "$", "$ 12.35"]`, nil},
{10, 123456, money.JSONExtended, true, `[12345.6, "$", "$ 12,345.60"]`, nil},
{100, 123456, money.JSONExtended, false, `null`, nil},
{0, 123456, money.JSONExtended, true, `[123456, "$", "$ 123,456.00"]`, nil},
}
for _, test := range tests {
c := money.New(
money.WithPrecision(test.prec),
).Set(test.haveI)
c.Valid = test.haveValid
c.FmtCur = testFmtCur
c.FmtNum = testFmtNum
c.Encoder = test.haveEnc
have, err := c.MarshalJSON()
if test.wantErr != nil {
assert.Error(t, err, "%v", test)
assert.Nil(t, have, "%v", test)
} else {
haveS := string(have)
assert.NoError(t, err, "%v", test)
if haveS != test.want {
// assert.Equal... is not useful in this case
t.Errorf("\nHave: %s\nWant: %s\n", haveS, test.want)
}
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:57,代码来源:encoding_test.go
示例6: TestAdd
func TestAdd(t *testing.T) {
tests := []struct {
have1 int64
have2 int64
want int64
}{
{13, 13, 26},
{-13, -13, -26},
{-45628734653, -45628734653, -91257469306},
{math.MaxInt64, 2, 0},
}
for _, test := range tests {
c := money.New().Set(test.have1)
c = c.Add(money.New().Set(test.have2))
have := c.Raw()
if have != test.want {
t.Errorf("\nWant: %d\nHave: %d\nIndex: %v\n", test.want, have, test)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:21,代码来源:money_test.go
示例7: TestSign
func TestSign(t *testing.T) {
tests := []struct {
have int64
want int
}{{13, 1}, {-13, -1}, {-45628734653, -1}, {45628734699, 1}}
for i, test := range tests {
c := money.New().Set(test.have)
have := c.Sign()
if have != test.want {
t.Errorf("\nWant: %d\nHave: %d\nIndex: %d\n", test.want, have, i)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:13,代码来源:money_test.go
示例8: TestMulNumber
func TestMulNumber(t *testing.T) {
tests := []struct {
prec int
have1 int64
have2 int64
want string
}{
{0, 1300, 1300, "1690000.000"},
{100, 1300, 1300, "169.000"},
{1000, 18100, 18100, "327.610"},
{100, 1319, 1488, "196.270"},
{1000, 1319, 1488, "1.963"},
{100, 13, -13, "-0.020"},
{100, 1300, -1300, "-169.000"},
{1000, 1300, -1300, "-1.690"},
{100, 13, 13, "0.020"},
{100, 45628734653, -45628734653, "250065429529630.200"}, // overflow of int64 ?
{100, 45628734653, -456287346, "-237307016244604.920"},
{100, math.MaxInt64, 2, "0.000"},
}
for _, test := range tests {
c := money.New(
money.WithPrecision(test.prec),
).Set(test.have1)
c.FmtCur = testFmtCur
c.FmtNum = testFmtNum
c = c.Mul(money.New(money.WithPrecision(test.prec)).Set(test.have2))
haveB, err := c.Number()
assert.NoError(t, err)
have := string(haveB)
if have != test.want {
t.Errorf("\nWant: %s\nHave: %s\nSign %d\nIndex: %v\n", test.want, have, c.Sign(), test)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:38,代码来源:money_test.go
示例9: Benchmark_NumberWriter
// Benchmark_NumberWriter 1000000 1692 ns/op 264 B/op 13 allocs/op => Go 1.4.2
// Benchmark_NumberWriter 1000000 1168 ns/op 224 B/op 7 allocs/op => Go 1.5.0
func Benchmark_NumberWriter(b *testing.B) {
var err error
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
c := money.New(money.WithPrecision(100)).Setf(-123456.789)
_, err = c.NumberWriter(&bufferNumberWriter)
if err != nil {
b.Error(err)
}
benchBenchmarkNumberWriter = string(bufferNumberWriter)
bufferNumberWriter = bufferNumberWriter[:0]
}
}
开发者ID:joao-parana,项目名称:csfw,代码行数:16,代码来源:money_bm_test.go
示例10: TestAbs
func TestAbs(t *testing.T) {
tests := []struct {
have int64
want int64
}{
{13, 13},
{-13, 13},
{-45628734653, 45628734653},
}
for i, test := range tests {
c := money.New().Set(test.have)
have := c.Abs().Raw()
if have != test.want {
t.Errorf("\nWant: %d\nHave: %d\nIndex: %d\n", test.want, have, i)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:18,代码来源:money_test.go
示例11: TestString
func TestString(t *testing.T) {
tests := []struct {
prec int
have int64
want string
}{
{0, 13, "$ 13.00"},
{10, 13, "$ 1.30"},
{100, 13, "$ 0.13"},
{1000, 13, "$ 0.01"},
{100, -13, "$ -0.13"},
{0, -45628734653, "$ -45,628,734,653.00"},
{10, -45628734653, "$ -4,562,873,465.30"},
{100, -45628734653, "$ -456,287,346.53"},
{1000, -45628734653, "$ -45,628,734.65"},
{100, 256, "$ 2.56"},
10: {1234, -45628734653, "$ -4,562,873.47"},
{100, -45628734655, "$ -456,287,346.55"},
{100, -45628734611, "$ -456,287,346.11"},
{100, -45628734699, "$ -456,287,346.99"},
14: {10000000, 45628734699, "$ 4,562.87"},
15: {10000000, 45628734655, "$ 4,562.87"},
}
for i, test := range tests {
c := money.New(
money.WithPrecision(test.prec),
).Set(test.have)
c.FmtCur = testFmtCur
c.FmtNum = testFmtNum
have := c.String()
if have != test.want {
t.Errorf("\nWant: %s\nHave: %s\nIndex: %d\n", test.want, have, i)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:38,代码来源:money_test.go
示例12: TestPrecisionAndGet
func TestPrecisionAndGet(t *testing.T) {
tests := []struct {
prec int
have int64
wanti int64
wantf float64
}{
{0, 13, 13, 13.0000},
{10, 13, 1, 1.30000},
{100, 13, 0, 0.130000},
{1000, 13, 0, 0.013000},
{100, -13, 0, -0.130000},
{0, -45628734653, -45628734653, -45628734653.000000},
{10, -45628734653, -4562873465, -4562873465.300000},
{100, -45628734653, -456287346, -456287346.530000},
{1000, -45628734653, -45628734, -45628734.653000},
{100, 256, 2, 2.56},
10: {1234, -45628734653, -4562873, -4562873.46530000}, // fallback to prec 10000
{100, -45628734655, -456287346, -456287346.550000},
{100, -45628734611, -456287346, -456287346.110000},
{100, -45628734699, -456287346, -456287346.990000},
14: {10000000, 45628734699, 4562, 4562.87346989999969082419},
15: {10000000, 45628734655, 4562, 4562.87346549999983835733},
}
for i, test := range tests {
c := money.New(money.WithPrecision(test.prec)).Set(test.have)
haveCI := c.Geti()
haveCF := c.Getf()
if haveCI != test.wanti {
t.Errorf("\nWantI: %d\nHaveI: %d\nIndex: %d\n", test.wanti, haveCI, i)
}
if haveCF != test.wantf {
t.Errorf("\nWantF: %f\nHaveF: %.20f\nIndex: %d\n", test.wantf, haveCF, i)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:38,代码来源:money_test.go
示例13: TestSwedishNumber
func TestSwedishNumber(t *testing.T) {
tests := []struct {
prec int
iv money.Interval
have int64
want string
}{
{0, money.Interval005, 25689, "25689.000"},
{100, money.Interval005, 25600, "256.000"},
{10, money.Interval005, 25689, "2568.900"},
{100, money.Interval005, 25689, "256.900"},
{1000, money.Interval005, 25689, "25.700"},
{100, money.Interval005, 25642, "256.400"},
{100, money.Interval005, 25644, "256.450"},
{0, money.Interval010, 25689, "25689.000"},
{10, money.Interval010, 25689, "2568.900"},
{100, money.Interval010, 25689, "256.900"},
{1000, money.Interval010, 25689, "25.700"},
{100, money.Interval010, 25642, "256.400"},
{100, money.Interval010, 25644, "256.400"},
{100, money.Interval010, 25639, "256.400"},
{100, money.Interval010, 25635, "256.400"},
{100, money.Interval010, 25634, "256.300"},
{100, money.Interval010, 256345, "2563.500"},
{0, money.Interval015, 25689, "25689.000"},
{10, money.Interval015, 25689, "2568.900"},
{10, money.Interval015, 25685, "2568.400"},
{100, money.Interval015, 25689, "256.900"},
{1000, money.Interval015, 25689, "25.700"},
{100, money.Interval015, 25642, "256.400"},
{100, money.Interval015, 25644, "256.400"},
{100, money.Interval015, 25639, "256.400"},
{100, money.Interval015, 25635, "256.300"},
{100, money.Interval015, 25636, "256.400"},
{100, money.Interval015, 25634, "256.300"},
{100, money.Interval015, 256345, "2563.400"},
{0, money.Interval025, 25689, "25689.000"},
{10, money.Interval025, 25689, "2569.000"},
{10, money.Interval025, 25685, "2568.500"},
{100, money.Interval025, 25689, "257.000"},
{1000, money.Interval025, 25689, "25.750"},
{100, money.Interval025, 25642, "256.500"},
{100, money.Interval025, 25644, "256.500"},
{100, money.Interval025, 25639, "256.500"},
{100, money.Interval025, 25624, "256.250"},
{100, money.Interval025, 25625, "256.250"},
{100, money.Interval025, 25634, "256.250"},
{100, money.Interval025, 256345, "2563.500"},
{0, money.Interval050, 25689, "25689.000"},
{10, money.Interval050, 25689, "2569.000"},
{10, money.Interval050, 25685, "2568.500"},
{100, money.Interval050, 25689, "257.000"},
{1000, money.Interval050, 25689, "25.500"},
{100, money.Interval050, 25642, "256.500"},
{100, money.Interval050, 25644, "256.500"},
{100, money.Interval050, 25639, "256.500"},
{100, money.Interval050, 25624, "256.000"},
{100, money.Interval050, 25625, "256.500"},
{100, money.Interval050, 25634, "256.500"},
{100, money.Interval050, 256345, "2563.500"},
{0, money.Interval100, 25689, "25689.000"},
{10, money.Interval100, 25689, "2569.000"},
{10, money.Interval100, 25685, "2569.000"},
{10, money.Interval100, 25684, "2568.000"},
{100, money.Interval100, 25689, "257.000"},
{1000, money.Interval100, 25689, "26.000"},
{100, money.Interval100, 25642, "256.000"},
{100, money.Interval100, 25644, "256.000"},
{100, money.Interval100, 25639, "256.000"},
{100, money.Interval100, 25624, "256.000"},
{100, money.Interval100, 25625, "256.000"},
{100, money.Interval100, 25634, "256.000"},
{100, money.Interval100, 256345, "2563.000"},
}
for _, test := range tests {
c := money.New(
money.WithPrecision(test.prec),
).Set(test.have)
c.FmtCur = testFmtCur
c.FmtNum = testFmtNum
haveB, err := c.Swedish(money.WithSwedish(test.iv)).Number()
assert.NoError(t, err, "%v", test)
have := string(haveB)
if have != test.want {
t.Errorf("\nWant: %s\nHave: %s\nIndex: %v\n", test.want, have, test)
}
}
}
开发者ID:levcom,项目名称:csfw,代码行数:95,代码来源:money_test.go
示例14: TestJSONEncode
func TestJSONEncode(t *testing.T) {
var peds = TableProductEntityDecimalSlice{
&TableProductEntityDecimal{ValueID: 1, AttributeID: 73, StoreID: 0, EntityID: 1, Value: money.New(money.WithPrecision(4)).Set(9990000)},
&TableProductEntityDecimal{ValueID: 2, AttributeID: 78, StoreID: 0, EntityID: 1, Value: money.New(money.WithPrecision(4))}, // null values
&TableProductEntityDecimal{ValueID: 3, AttributeID: 74, StoreID: 0, EntityID: 1, Value: money.New(money.WithPrecision(4))}, // null values
&TableProductEntityDecimal{ValueID: 4, AttributeID: 77, StoreID: 0, EntityID: 1, Value: money.New(money.WithPrecision(4))}, // null values
&TableProductEntityDecimal{ValueID: 5, AttributeID: 73, StoreID: 1, EntityID: 1, Value: money.New(money.WithPrecision(4)).Set(7059933)},
&TableProductEntityDecimal{ValueID: 6, AttributeID: 73, StoreID: 4, EntityID: 1, Value: money.New(money.WithPrecision(4)).Set(7059933)},
&TableProductEntityDecimal{ValueID: 7, AttributeID: 73, StoreID: 2, EntityID: 1, Value: money.New(money.WithPrecision(4)).Set(7059933)},
&TableProductEntityDecimal{ValueID: 8, AttributeID: 73, StoreID: 3, EntityID: 1, Value: money.New(money.WithPrecision(4)).Set(7059933)},
}
jb, err := json.Marshal(peds)
assert.NoError(t, err)
have := string(jb)
want := `[{"ValueID":1,"AttributeID":73,"StoreID":0,"EntityID":1,"Value":"$\u00A0999.00"},{"ValueID":2,"AttributeID":78,"StoreID":0,"EntityID":1,"Value":null},{"ValueID":3,"AttributeID":74,"StoreID":0,"EntityID":1,"Value":null},{"ValueID":4,"AttributeID":77,"StoreID":0,"EntityID":1,"Value":null},{"ValueID":5,"AttributeID":73,"StoreID":1,"EntityID":1,"Value":"$\u00A0705.99"},{"ValueID":6,"AttributeID":73,"StoreID":4,"EntityID":1,"Value":"$\u00A0705.99"},{"ValueID":7,"AttributeID":73,"StoreID":2,"EntityID":1,"Value":"$\u00A0705.99"},{"ValueID":8,"AttributeID":73,"StoreID":3,"EntityID":1,"Value":"$\u00A0705.99"}]`
if have != want {
t.Errorf("\nHave: %s\n\nWant: %s\n", have, want)
}
}
开发者ID:levcom,项目名称:csfw,代码行数:21,代码来源:encoding_test.go
示例15: TestValue
func TestValue(t *testing.T) {
dbrSess := csdb.MustConnectTest().NewSession()
tuple := &TableProductEntityDecimal{ValueID: 0, AttributeID: 73, StoreID: 3, EntityID: 231, Value: money.New(money.WithPrecision(4)).Set(7779933)}
tuple2 := &TableProductEntityDecimal{ValueID: 0, AttributeID: 74, StoreID: 2, EntityID: 231, Value: money.New(money.WithPrecision(4)).Set(8889933)}
ib := dbrSess.InsertInto("catalog_product_entity_decimal")
ib.Columns("attribute_id", "store_id", "entity_id", "value")
ib.Values(tuple.AttributeID, tuple.StoreID, tuple.EntityID, tuple.Value)
ib.Values(tuple2.AttributeID, tuple2.StoreID, tuple2.EntityID, &tuple2.Value)
sql, args := ib.ToSql()
fullSql, err := dbr.Preprocess(sql, args)
assert.NoError(t, err)
assert.Contains(t, fullSql, `(73,3,231,777.9933),(74,2,231,888.9933)`)
}
开发者ID:levcom,项目名称:csfw,代码行数:16,代码来源:encoding_test.go
示例16: TestSaveToDb
func TestSaveToDb(t *testing.T) {
//for hacking testing added :-)
db := csdb.MustConnectTest()
defer db.Close()
dbrSess := dbr.NewConnection(db, nil).NewSession(nil)
// var peds = TableProductEntityDecimalSlice{
// &TableProductEntityDecimal{ValueID: 1, AttributeID: 73, StoreID: 0, EntityID: 1, Value: money.New(money.Precision(4)).Set(9990000)},
// &TableProductEntityDecimal{ValueID: 2, AttributeID: 78, StoreID: 0, EntityID: 1, Value: money.New(money.Precision(4))}, // null values
// &TableProductEntityDecimal{ValueID: 3, AttributeID: 74, StoreID: 0, EntityID: 1, Value: money.New(money.Precision(4))}, // null values
// &TableProductEntityDecimal{ValueID: 4, AttributeID: 77, StoreID: 0, EntityID: 1, Value: money.New(money.Precision(4))}, // null values
// &TableProductEntityDecimal{ValueID: 5, AttributeID: 73, StoreID: 1, EntityID: 1, Value: money.New(money.Precision(4)).Set(7059933)},
// &TableProductEntityDecimal{ValueID: 6, AttributeID: 73, StoreID: 4, EntityID: 1, Value: money.New(money.Precision(4)).Set(7059933)},
// &TableProductEntityDecimal{ValueID: 7, AttributeID: 73, StoreID: 2, EntityID: 1, Value: money.New(money.Precision(4)).Set(7059933)},
// &TableProductEntityDecimal{ValueID: 8, AttributeID: 73, StoreID: 3, EntityID: 1, Value: money.New(money.Precision(4)).Set(7059933)},
// }
tuple := &TableProductEntityDecimal{ValueID: 0, AttributeID: 73, StoreID: 3, EntityID: 231, Value: money.New(money.Precision(4)).Set(7779933)}
tuple2 := &TableProductEntityDecimal{ValueID: 0, AttributeID: 74, StoreID: 2, EntityID: 231, Value: money.New(money.Precision(4)).Set(8889933)}
ib := dbrSess.InsertInto("catalog_product_entity_decimal")
ib.Columns("attribute_id", "store_id", "entity_id", "value")
ib.Values(tuple.AttributeID, tuple.StoreID, tuple.EntityID, &tuple.Value)
ib.Values(tuple2.AttributeID, tuple2.StoreID, tuple2.EntityID, &tuple2.Value)
// t.Error(ib.ToSql())
res, err := ib.Exec()
t.Log(err)
t.Logf("%#v", res)
t.Log(res.LastInsertId())
t.Log(res.RowsAffected())
}
开发者ID:bom-d-van,项目名称:csfw,代码行数:32,代码来源:encoding_test.go
注:本文中的github.com/corestoreio/csfw/storage/money.New函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论