Ei kuvausta

chapter3-others-about-generics.slide 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # More on type sets
  2. Qinghe
  3. 21 Jan 2022
  4. ## Both elements and methods in constraints
  5. 约束中可以同时约束元素(具体类型、近似类型、联合类型)和方法。
  6. .code codes/type_sets.go /StringableSignedInteger OMIT/,/StringableSignedInteger OMIT/
  7. 满足这个约束的类型必须满足两个条件:
  8. 1. 底层类型是int/int8/int16/int32/int64类型其中之一
  9. 2. 这个类型必须有`String() string`方法
  10. 要注意:
  11. `'~'`符号是必要的,因为int类型本身没有实现`String() string`方法,否则语法检查能通过,但是满足条件的类型集合为空。
  12. ## Composite types in constraints
  13. 复合类型包括以下几种:
  14. - string
  15. - pointer
  16. - array
  17. - slice
  18. - struct
  19. - function
  20. - map
  21. - channel
  22. ## Composite types in constraints
  23. 在约束中使用复合类型:
  24. .code codes/type_sets.go /COMPOSITE TYPE OMIT/,/COMPOSITE TYPE OMIT/
  25. ## Composite types in constraints
  26. 对于复合类型的使用,有个额外的限制:对于所有的类型集中的类型,只有输入以及输出类型均完全一致的操作才允许使用。
  27. 例如:
  28. .code codes/type_sets.go /COMPOSITE STRUCT FIELD OMIT/,/COMPOSITE STRUCT FIELD OMIT/
  29. (当然目前即使上面例子中各个struct的x字段类型一致也无法执行,因为这个特性在1.18中已经被移除,后续版本中可能会加回来,详情见[issue#50417](https://github.com/golang/go/issues/50417)、[issue#51576](https://github.com/golang/go/issues/51576))
  30. ## Type conversions
  31. 如果要对两个类型参数From和To类型的变量进行类型转换,则需要From的约束所包含的所有类型均能够转换为To的约束所包含的任一类型。
  32. 例如:
  33. .code codes/type_sets.go /TYPE CONVERSION OMIT/,/TYPE CONVERSION OMIT/
  34. ## Untyped constants
  35. 泛型函数中可能会使用到无类型常量,在使用无类型常量的时候,仅当约束中所包含的所有类型都可以正常使用无类型常量。
  36. .code codes/type_sets.go /UNTYPED CONSTANTS OMIT/,/UNTYPED CONSTANTS OMIT/
  37. ## Type sets of embedded constraints
  38. .code codes/type_sets.go /EMBED INTERSECTION OMIT/,/EMBED INTERSECTION OMIT/
  39. ## Type sets of embedded constraints
  40. .code codes/type_sets.go /EMBED UNION OMIT/,/EMBED UNION OMIT/
  41. ## Interface types in union elements
  42. .code codes/type_sets.go /INTERFACE IN UNION OMIT/,/INTERFACE IN UNION OMIT/
  43. - 约束的类型集包括string类型以及实现了fmt.Stringer接口的所有类型
  44. - 除所有类型都共有的操作外,无其他特殊的允许的操作
  45. - 必须通过断言或者反射来使用对应的值
  46. 目前版本还未实现,see [issue#49054](https://github.com/golang/go/issues/49054),[issue#45346 (comment)](https://github.com/golang/go/issues/45346#issuecomment-862505803)
  47. ## Empty type sets
  48. .code codes/type_sets.go /EMPTY TYPE SETS OMIT/,/EMPTY TYPE SETS OMIT/
  49. - 可以正常编译,但无法实例化
  50. - go vet 对某些能够被检测出来的情况“应该”报出错误
  51. ## Some Issues
  52. ## The zero value
  53. .code codes/zero_value.go /ZERO VALUE OMIT/,/ZERO VALUE OMIT/
  54. 一些可行的方案:
  55. - 使用`var zero T; return zero`,与现行方案不冲突,但是需要额外的代码
  56. - 使用`return *new(T)`,语法比较奇怪,但是也能正常执行
  57. - 使用命名返回值,返回值用return即可返回零值。此种方案仅对在返回值中生效
  58. - 允许使用nil作为参数类型的零值返回
  59. - 允许使用T{}作为参数类型的零值返回
  60. - 允许在赋值语句(包括return以及函数调用)的右边使用`_`作为零值
  61. - 允许使用`return ...`来返回对应类型的零值
  62. ## Identifying the matched predeclared type
  63. .code codes/type_assertion.go /TYPE ASSERTION OMIT/,/TYPE ASSERTION OMIT/
  64. 并不想知道v的真实类型,只想知道v的底层是float32还是float64,但目前无法做到。
  65. 一种解决方法是扩展switch case语法,支持`case ~float32:`类型的语句,甚至在泛型函数之外也应该可以使用这样的语法。
  66. ## No parameterized methods
  67. (略)
  68. ## No way to require pointer methods
  69. (略)