@@ -840,19 +840,19 @@ may be useful when considering future extensions to the Python type system.
840
840
C++
841
841
---
842
842
843
- C++ uses angle brackets in combination with keywords " template" and
844
- " typename" to declare type parameters. It uses angle brackets for
843
+ C++ uses angle brackets in combination with keywords `` template `` and
844
+ `` typename `` to declare type parameters. It uses angle brackets for
845
845
specialization.
846
846
847
847
C++20 introduced the notion of generalized constraints, which can act
848
848
like protocols in Python. A collection of constraints can be defined in
849
- a named entity called a " concept" .
849
+ a named entity called a `` concept `` .
850
850
851
851
Variance is not explicitly specified, but constraints can enforce variance.
852
852
853
- A default type argument can be specified using the "=" operator.
853
+ A default type argument can be specified using the `` = `` operator.
854
854
855
- ::
855
+ .. code-block :: c++
856
856
857
857
// Generic class
858
858
template <typename>
@@ -896,39 +896,44 @@ Java
896
896
----
897
897
898
898
Java uses angle brackets to declare type parameters and for specialization.
899
- The "extends" keyword is used to specify an upper bound.
899
+ By default, type parameters are invariant.
900
+ The ``extends `` keyword is used to specify an upper bound. The ``super `` keyword
901
+ is used to specify a contravariant bound.
900
902
901
903
Java uses use-site variance. The compiler places limits on which methods and
902
904
members can be accessed based on the use of a generic type. Variance is
903
905
not specified explicitly.
904
906
905
907
Java provides no way to specify a default type argument.
906
908
907
- ::
909
+ .. code-block :: java
908
910
909
911
// Generic class
910
912
public class ClassA <T> {
911
913
public Container<T > t;
912
914
913
915
// Generic method
914
916
public <S extends Number > void method1 (S value ) { }
917
+
918
+ // Use site variance
919
+ public void method1 (ClassA<? super Integer > value ) { }
915
920
}
916
921
917
922
918
923
C#
919
924
--
920
925
921
926
C# uses angle brackets to declare type parameters and for specialization.
922
- The " where" keyword and a colon is used to specify the bound for a type
927
+ The `` where `` keyword and a colon is used to specify the bound for a type
923
928
parameter.
924
929
925
- C# uses declaration-site variance using the keywords "in" and " out" for
930
+ C# uses declaration-site variance using the keywords `` in `` and `` out `` for
926
931
contravariance and covariance, respectively. By default, type parameters are
927
932
invariant.
928
933
929
934
C# provides no way to specify a default type argument.
930
935
931
- ::
936
+ .. code-block :: c#
932
937
933
938
// Generic class with bounds on type parameters
934
939
public class ClassA <S , T >
@@ -951,20 +956,21 @@ TypeScript
951
956
----------
952
957
953
958
TypeScript uses angle brackets to declare type parameters and for
954
- specialization. The " extends" keyword is used to specify a bound. It can be
955
- combined with other type operators such as " keyof" .
959
+ specialization. The `` extends `` keyword is used to specify a bound. It can be
960
+ combined with other type operators such as `` keyof `` .
956
961
957
962
TypeScript uses declaration-site variance. Variance is inferred from
958
- usage, not specified explicitly. TypeScript 4.7 will introduce the ability
959
- to specify variance using "in" and "out" keywords. This was added to handle
960
- extremely complex types where inference of variance was expensive.
963
+ usage, not specified explicitly. TypeScript 4.7 introduced the ability
964
+ to specify variance using ``in `` and ``out `` keywords. This was added to handle
965
+ extremely complex types where inference of variance was expensive,
966
+ yet the maintainers state that is useful for increasing readability.
961
967
962
- A default type argument can be specified using the "=" operator.
968
+ A default type argument can be specified using the `` = `` operator.
963
969
964
- TypeScript supports the " type" keyword to declare a type alias, and this
970
+ TypeScript supports the `` type `` keyword to declare a type alias, and this
965
971
syntax supports generics.
966
972
967
- ::
973
+ .. code-block :: typescript
968
974
969
975
// Generic interface
970
976
interface InterfaceA <S , T extends SomeInterface1 > {
@@ -991,19 +997,19 @@ Scala
991
997
-----
992
998
993
999
In Scala, square brackets are used to declare type parameters. Square
994
- brackets are also used for specialization. The "<:" and ">:" operators
1000
+ brackets are also used for specialization. The `` <: `` and `` >: `` operators
995
1001
are used to specify upper and lower bounds, respectively.
996
1002
997
1003
Scala uses use-site variance but also allows declaration-site variance
998
- specification. It uses a "+" or "-" prefix operator for covariance and
1004
+ specification. It uses a `` + `` or `` - `` prefix operator for covariance and
999
1005
contravariance, respectively.
1000
1006
1001
1007
Scala provides no way to specify a default type argument.
1002
1008
1003
1009
It does support higher-kinded types (type parameters that accept type
1004
1010
type parameters).
1005
1011
1006
- ::
1012
+ .. code-block :: scala
1007
1013
1008
1014
1009
1015
// Generic class; type parameter has upper bound
@@ -1036,17 +1042,16 @@ Swift
1036
1042
Swift uses angle brackets to declare type parameters and for specialization.
1037
1043
The upper bound of a type parameter is specified using a colon.
1038
1044
1039
- Swift uses declaration-site variance, and variance of type parameters is
1040
- inferred from their usage.
1045
+ Swift doesn't support generic variance; all type parameters are invariant.
1041
1046
1042
1047
Swift provides no way to specify a default type argument.
1043
1048
1044
- ::
1049
+ .. code-block :: swift
1045
1050
1046
1051
// Generic class
1047
1052
class ClassA <T > {
1048
1053
// Generic method
1049
- func method1<X>(val: T) -> S { }
1054
+ func method1 <X >(val : T) -> X { }
1050
1055
}
1051
1056
1052
1057
// Type parameter with upper bound constraint
@@ -1061,23 +1066,33 @@ Rust
1061
1066
1062
1067
Rust uses angle brackets to declare type parameters and for specialization.
1063
1068
The upper bound of a type parameter is specified using a colon. Alternatively
1064
- a " where" clause can specify various constraints.
1069
+ a `` where `` clause can specify various constraints.
1065
1070
1066
- Rust uses declaration-site variance, and variance of type parameters is
1067
- typically inferred from their usage. In cases where a type parameter is not
1068
- used within a type, variance can be specified explicitly .
1071
+ Rust does not have traditional object oriented inheritance or variance.
1072
+ Subtyping in Rust is very restricted and occurs only due to variance with
1073
+ respect to lifetimes .
1069
1074
1070
- A default type argument can be specified using the "=" operator.
1075
+ A default type argument can be specified using the `` = `` operator.
1071
1076
1072
- ::
1077
+ .. code-block :: rust
1073
1078
1074
1079
// Generic class
1075
- struct StructA<T> {
1080
+ struct StructA<T> { // T's lifetime is inferred as covariant
1076
1081
x: T
1077
1082
}
1078
1083
1084
+ fn f<'a>(
1085
+ mut short_lifetime: StructA<&'a i32>,
1086
+ mut long_lifetime: StructA<&'static i32>,
1087
+ ) {
1088
+ long_lifetime = short_lifetime;
1089
+ // error: StructA<&'a i32> is not a subtype of StructA<&'static i32>
1090
+ short_lifetime = long_lifetime;
1091
+ // valid: StructA<&'static i32> is a subtype of StructA<&'a i32>
1092
+ }
1093
+
1079
1094
// Type parameter with bound
1080
- struct StructB<T: StructA > {}
1095
+ struct StructB<T: SomeTrait > {}
1081
1096
1082
1097
// Type parameter with additional constraints
1083
1098
struct StructC<T>
@@ -1089,56 +1104,55 @@ A default type argument can be specified using the "=" operator.
1089
1104
// Generic function
1090
1105
fn func1<T>(val: &[T]) -> T { }
1091
1106
1092
- // Explicit variance specification
1093
- use type_variance::{Covariant, Contravariant};
1094
-
1095
- struct StructD<A, R> {
1096
- arg: Covariant<A>,
1097
- ret: Contravariant<R>,
1098
- }
1099
-
1100
1107
// Generic type alias
1101
- type MyType<T> = StructC<T>
1108
+ type MyType<T> = StructC<T>;
1102
1109
1103
1110
1104
1111
Kotlin
1105
1112
------
1106
1113
1107
1114
Kotlin uses angle brackets to declare type parameters and for specialization.
1108
- The upper bound of a type is specified using a colon.
1115
+ By default, type parameters are invariant. The upper bound of a type is
1116
+ specified using a colon.
1117
+ Alternatively, a ``where `` clause can specify various constraints.
1109
1118
1110
1119
Kotlin supports declaration-site variance where variance of type parameters is
1111
- explicitly declared using "in" and " out" keywords. It also supports use-site
1120
+ explicitly declared using `` in `` and `` out `` keywords. It also supports use-site
1112
1121
variance which limits which methods and members can be used.
1113
1122
1114
1123
Kotlin provides no way to specify a default type argument.
1115
1124
1116
- ::
1125
+ .. code-block :: kotlin
1117
1126
1118
1127
// Generic class
1119
- class ClassA<T> { }
1128
+ class ClassA<T>
1120
1129
1121
1130
// Type parameter with upper bound
1122
- class ClassB<T: SomeClass1> { }
1131
+ class ClassB<T : SomeClass1>
1123
1132
1124
1133
// Contravariant and covariant type parameters
1125
- class ClassC<in S, out T> { }
1134
+ class ClassC<in S, out T>
1126
1135
1127
1136
// Generic function
1128
- fun func1<T>() -> T {}
1137
+ fun <T> func1(): T {
1138
+
1139
+ // Use site variance
1140
+ val covariantA: ClassA<out Number>
1141
+ val contravariantA: ClassA<in Number>
1142
+ }
1129
1143
1130
1144
// Generic type alias
1131
- typealias<T> = ClassA<T>
1145
+ typealias TypeAliasFoo <T> = ClassA<T>
1132
1146
1133
1147
1134
1148
Julia
1135
1149
-----
1136
1150
1137
1151
Julia uses curly braces to declare type parameters and for specialization.
1138
- The "<:" operator can be used within a " where" clause to declare
1152
+ The `` <: `` operator can be used within a `` where `` clause to declare
1139
1153
upper and lower bounds on a type.
1140
1154
1141
- ::
1155
+ .. code-block :: julia
1142
1156
1143
1157
// Generic struct; type parameter with upper and lower bounds
1144
1158
struct StructA{T} where Int <: T <: Number
@@ -1151,6 +1165,62 @@ upper and lower bounds on a type.
1151
1165
// Alternate form of generic function
1152
1166
function func2(v::Container{T} where T <: Real)
1153
1167
1168
+ Dart
1169
+ ----
1170
+
1171
+ Dart uses angle brackets to declare type parameters and for specialization.
1172
+ The upper bound of a type is specified using the ``extends `` keyword.
1173
+ By default, type parameters are covariant.
1174
+
1175
+ Dart supports declaration-site variance, where variance of type parameters is
1176
+ explicitly declared using ``in ``, ``out `` and ``inout `` keywords.
1177
+ It does not support use-site variance.
1178
+
1179
+ Dart provides no way to specify a default type argument.
1180
+
1181
+ .. code-block :: dart
1182
+
1183
+ // Generic class
1184
+ class ClassA<T> { }
1185
+
1186
+ // Type parameter with upper bound
1187
+ class ClassB<T extends SomeClass1> { }
1188
+
1189
+ // Contravariant and covariant type parameters
1190
+ class ClassC<in S, out T> { }
1191
+
1192
+ // Generic function
1193
+ T func1<T>() { }
1194
+
1195
+ // Generic type alias
1196
+ typedef TypeDefFoo<T> = ClassA<T>;
1197
+
1198
+ Go
1199
+ --
1200
+
1201
+ Go uses square brackets to declare type parameters and for specialization.
1202
+ The upper bound of a type is specified after the name of the parameter, and
1203
+ must always be specified. The keyword ``any `` is used for an unbound type parameter.
1204
+
1205
+ Go doesn't support variance; all type parameters are invariant.
1206
+
1207
+ Go provides no way to specify a default type argument.
1208
+
1209
+ Go does not support generic type aliases.
1210
+
1211
+ .. code-block :: go
1212
+
1213
+ // Generic type without a bound
1214
+ type TypeA[T any] struct {
1215
+ t T
1216
+ }
1217
+
1218
+ // Type parameter with upper bound
1219
+ type TypeB[T SomeType1] struct { }
1220
+
1221
+ // Generic function
1222
+ func func1[T any]() { }
1223
+
1154
1224
1155
1225
Summary
1156
1226
-------
@@ -1162,7 +1232,8 @@ Summary
1162
1232
| C++ | template | n/a | n/a | = | n/a | n/a |
1163
1233
| | <> | | | | | |
1164
1234
+------------+----------+---------+--------+----------+-----------+-----------+
1165
- | Java | <> | extends | | | use | inferred |
1235
+ | Java | <> | extends | | | use | super, |
1236
+ | | | | | | | extends |
1166
1237
+------------+----------+---------+--------+----------+-----------+-----------+
1167
1238
| C# | <> | where | | | decl | in, out |
1168
1239
+------------+----------+---------+--------+----------+-----------+-----------+
@@ -1171,15 +1242,21 @@ Summary
1171
1242
+------------+----------+---------+--------+----------+-----------+-----------+
1172
1243
| Scala | [] | T <: X | T >: X | | use, decl | +, - |
1173
1244
+------------+----------+---------+--------+----------+-----------+-----------+
1174
- | Swift | <> | T: X | | | decl | inferred |
1245
+ | Swift | <> | T: X | | | n/a | n/a |
1175
1246
+------------+----------+---------+--------+----------+-----------+-----------+
1176
- | Rust | <> | T: X, | | = | decl | inferred, |
1177
- | | | where | | | | explicit |
1247
+ | Rust | <> | T: X, | | = | n/a | n/a |
1248
+ | | | where | | | | |
1178
1249
+------------+----------+---------+--------+----------+-----------+-----------+
1179
- | Kotlin | <> | T: X | | | use, decl | inferred |
1250
+ | Kotlin | <> | T: X, | | | use, decl | in, out |
1251
+ | | | where | | | | |
1180
1252
+------------+----------+---------+--------+----------+-----------+-----------+
1181
1253
| Julia | {} | T <: X | X <: T | | n/a | n/a |
1182
1254
+------------+----------+---------+--------+----------+-----------+-----------+
1255
+ | Dart | <> | extends | | | decl | in, out, |
1256
+ | | | | | | | inout |
1257
+ +------------+----------+---------+--------+----------+-----------+-----------+
1258
+ | Go | [] | T X | | | n/a | n/a |
1259
+ +------------+----------+---------+--------+----------+-----------+-----------+
1183
1260
| Python | [] | T: X | | | decl | inferred |
1184
1261
| (proposed) | | | | | | |
1185
1262
+------------+----------+---------+--------+----------+-----------+-----------+
0 commit comments