Generics, or “parameterized types”, parameterize types and can be used on classes, interfaces, and methods.
Same as Java Kotlin generics are also provided to ensure type safety and eliminate the annoyance of type overturning.
Declare a generic class:
class Box<T>(t: T) { var value = t } We need to specify the type parameters when creating an instance of the class:
val box: Box<Int> = Box<Int>(1) // or val box = Box(1) // The compiler will perform type inference, type 1 is Int, so the compiler knows that we are referring to Box<Int>. The following example gives a generic class Box pass in integer data and strings:
class Box<T>(t : T) { var value = t } fun main(args: Array<String>) { var boxInt = Box<Int>(10) var boxString = Box<String>("Runoob") println(boxInt.value) println(boxString.value) } The output is as follows:
10 Runoob By defining generic type variables, you can fully specify the type parameters, and if the compiler can automatically deduce the type parameters, you can also omit them.
Kotlin declaration of generic functions and Java similarly, the type parameter should be placed before the function name:
fun <T> boxIn(value: T) = Box(value) // The following are all legal statements val box4 = boxIn<Int>(1) val box5 = boxIn(1) // The compiler will perform type inference When calling a generic function, if you can infer the type parameters, you can omit the generic parameters.
The following example creates a generic function doPrintln . The functionshould be handled accordingly according to the different types passed in:
fun main(args: Array<String>) { val age = 23 val name = "runoob" val bool = true doPrintln(age) // integer doPrintln(name) // character string doPrintln(bool) // Boolean type } fun <T> doPrintln(content: T) { when (content) { is Int -> println("Integer number is $content") is String -> println("Convert string to uppercase:${content.toUpperCase()}") else -> println("T is not an integer or a string") } } The output is as follows:
The integer number is 23 Convert string to uppercase: RUNOOB T is not an integer or a string 3.15.1. Generic constraint #
We can use generic constraints to set the type allowed for a given parameter.
Kotlin use in: constrains the type upper limit of generics.
The most common constraint is the upper bound:
fun > sort(list: List) { // …… } Comparable can be replaced by the subtype of T . For example:
sort(listOf(1, 2, 3)) // OK。Int is the subtype of Comparable sort(listOf(HashMap())) // error:HashMap is not the subtype of Comparable> The default upper bound is Any? .
For multiple upper bound constraints, you can use the where clause:
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String> where T : CharSequence, T : Comparable<T> { return list.filter { it > threshold }.map { it.toString() } }
3.15.2. Shape change #
There are no wildcard types in Kotlin , it has two other things: declaration-site variance at the declaration point and type projection (typeprojections).
3.15.3. Declaration place type change #
The type variation at the declaration uses the covariant annotation modifier: in 、 out consumers in producer out .
Use out to make a type parameter covariant, the covariant type parameter can only be used as an output, can be used as a return value type,but cannot be used as an input parameter:
// Define a class that supports covariation class Runoob<out A>(val a: A) { fun foo(): A { return a } } fun main(args: Array<String>) { var strCo: Runoob<String> = Runoob("a") var anyCo: Runoob<Any> = Runoob<Any>("b") anyCo = strCo println(anyCo.foo()) // Output a }
So that a type parameter in is inverted, and the inverter type parametercan only be used as input, and can be used as the type of input parameter but not as the type of return value:
// Define a class that supports inversion class Runoob<in A>(a: A) { fun foo(a: A) { } } fun main(args: Array<String>) { var strDCo = Runoob("a") var anyDCo = Runoob<Any>("b") strDCo = anyDCo }
3.15.4. Asterisk projection #
Sometimes, you may want to show that you don’t know any information about type parameters, but still want to be able to use it safely. The so-called “safe use” here means that a type projection is defined for a generic type, requiring that all entity instances of the generic type are subtypes of this projection.
As for this question, Kotlin provides a syntax called asterisk projection (star-projection):
-
If the type is defined as Foo T> , where T is a covariant type parameter with an upper bound of TUpper , and Foo<*> is equivalent to Foo TUpper> . It means that when T is unknown, you can safely read values of type TUpper from Foo<*> . -
If the type is defined as Foo T> where T is a reverse covariant typeparameter Foo<*> equivalent to Foo . It means that when T is unknown, you cannot safely report to Foo<*> . -
If the type is defined as Foo where T is a covariant type parameter and the upper bound (upper bound) is TUpper for the case of reading values Foo<*> equivalent to Foo TUpper> in the case of writinga value, it is equivalent to Foo Nothing> . If there are multiple type parameters in a generic type, each type parametercan be projected separately. For example, if the type is defined as interface Function T, out U> , then the following asterisk projections can occur: -
Function<*, String> ,representative Function Nothing, String> ; -
Function<*, String> ,representative Function Nothing, String> ; -
Function< *,* > , representative Function Nothing, out Any?> . Note: asterisk projection is very similar to Java’s native type (raw type), but can be used safely
-
1. Angularjs2
8
-
1. SVG tutorial
19
-
1. Memcached
20
-
1. C# tutorial
61
-
1. Sqlite
47
-
2. Go
43
-
2. Docker
59
-
2. Vue3
19
-
2. Servlet
21
-
3. React
23
-
3. SOAP tutorial
10
-
3. Android
18
-
3. Mongodb
44
-
3. Kotlin
18
-
3.16. Kotlin enumerated class
-
3.1. Kotlin tutorial
-
3.8. Kotlin conditional control
-
3.17. Kotlin object expressions and object declarations
-
3.5. Kotlin Android environment building
-
3.9. Kotlin cycle control
-
3.14. Kotlin data class and sealed class
-
3.7. Kotlin basic data type
-
3.11. Kotlin inheritance
-
3.10. Kotlin classes and objects
-
4. Lua
31
-
4. MySQL tutorial
35
-
4. Appml
12
-
5. Perl
45
-
5. Postgresql
41
-
web
15
-
5. Web Services tutorial
6
-
6. Ruby
42
-
6. Design-pattern
35
-
7. Django
18
-
7. Rust
22
-
6. WSDL tutorial
8
-
8. Foundation
39
-
9. Ios
43
-
8. Css3
26
-
9. Swift
44
-
11. HTML tutorial-(HTML5 Standard)
54
-
12. Http
6
-
13. Regex
6
-
14. Regexp
8
《地理信息系统原理、技术与方法》
97
最近几年来,地理信息系统无论是在理论上还是应用上都处在一个飞速发展的阶段。 GIS被应用于多个领域的建模和决策支持,如城市管理、区划、环境整治等等,地理信息成为信息时代重要的组成部分之一; “数字地球”概念的提出,更进一步推动了作为其技术支撑的GIS的发展。 与此同时,一些学者致力于相关的理论研究,如空间感知、空间数据误差、空间关系的形式化等等。 这恰好说明了地理信息系统作为应用技术和学科的两个方面,并且这两个方面构成了相互促进的发展过程。
-
1. Introduction to geographic information system
6
-
2. From the Real World to the Bit World
3
-
3. Spatial Data Model
7
-
4. 空间参照系统和 地图投影
5
-
5. Data in GIS
3
-
6. Spatial data acquisition
2
-
7. Spatial Data Management
6
-
8. Spatial analysis
8
-
9. 数字地形模型( DTM )与地形分析
5
-
10. 空间建模与 空间决策支持
6
-
11. Spatial data representation and map making
6
-
12. 3S Integration Technology
5
-
13. 网络地理信息系统
3
-
14. Examples of Geographic Information System Application
8
-
15. Organization and Management of Geographic Information System Application Projects
9
-
16. Geographic Information system Software Engineering Technology
6
-
17. Geographic Information System Standards
3
-
18. Geographic Information System and Society
3
-
19. Earth Information Science and Digital Earth
3