(t reflect.Type, vx, vy reflect.Value)
| 373 | } |
| 374 | |
| 375 | func (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) { |
| 376 | var addr bool |
| 377 | var vax, vay reflect.Value // Addressable versions of vx and vy |
| 378 | |
| 379 | var mayForce, mayForceInit bool |
| 380 | step := StructField{&structField{}} |
| 381 | for i := 0; i < t.NumField(); i++ { |
| 382 | step.typ = t.Field(i).Type |
| 383 | step.vx = vx.Field(i) |
| 384 | step.vy = vy.Field(i) |
| 385 | step.name = t.Field(i).Name |
| 386 | step.idx = i |
| 387 | step.unexported = !isExported(step.name) |
| 388 | if step.unexported { |
| 389 | if step.name == "_" { |
| 390 | continue |
| 391 | } |
| 392 | // Defer checking of unexported fields until later to give an |
| 393 | // Ignore a chance to ignore the field. |
| 394 | if !vax.IsValid() || !vay.IsValid() { |
| 395 | // For retrieveUnexportedField to work, the parent struct must |
| 396 | // be addressable. Create a new copy of the values if |
| 397 | // necessary to make them addressable. |
| 398 | addr = vx.CanAddr() || vy.CanAddr() |
| 399 | vax = makeAddressable(vx) |
| 400 | vay = makeAddressable(vy) |
| 401 | } |
| 402 | if !mayForceInit { |
| 403 | for _, xf := range s.exporters { |
| 404 | mayForce = mayForce || xf(t) |
| 405 | } |
| 406 | mayForceInit = true |
| 407 | } |
| 408 | step.mayForce = mayForce |
| 409 | step.paddr = addr |
| 410 | step.pvx = vax |
| 411 | step.pvy = vay |
| 412 | step.field = t.Field(i) |
| 413 | } |
| 414 | s.compareAny(step) |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | func (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) { |
| 419 | isSlice := t.Kind() == reflect.Slice |
no test coverage detected