什么是占位符?为什么我们需要为泛型定义占位符数据类型? [英] What's a placeholder? Why do we need to define placeholder data type for generics?

查看:231
本文介绍了什么是占位符?为什么我们需要为泛型定义占位符数据类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  func inspect< SomeType> (value:SomeType){
print(Received \(type:of value)),其值为\(value))
}

我正在关注Pro Swift书中的一个教程,但我不明白为什么我们需要< SomeType> 。这似乎没有必要。

作者自己说:


注意使用SomeType:在
函数名称后面的尖括号中有一个,另一个用于描述value参数。尖括号中的第一个
是最重要的,因为它定义了
的占位符数据类型:inspect()表示有一个名为inspect()的
函数,可以与任何类型的数据类型
,但不管使用什么数据类型,我想把它称为
SomeType。因此,参数值:SomeType现在应该使更多
感觉到:SomeType将被替换为用于
的函数的任何数据类型。


我无法理解,也不明白占位符数据类型的含义是什么?



编辑:

或者更好的例子


  func inspect< T> (value1:T,value2:T){
// ....
}

我的问题:我知道T会执行value1& value2具有相同的类型,那么< T> 的用例是怎样的?

解决方案<

$ c $< T> ),看看会发生什么:

  func inspect(value1:T ,value2:T){

//对value1进行一些操作,value2
}

这里 T 是什么?是 T 一个班级?或者它是你想要的通用类型?仅仅因为你用 T 写了一些东西,它不会奇迹般地转化为泛型。



为了更好地说明问题,请看这段代码:

  func inspect (value1:T,value2:T){
//对value1进行一些操作,value2

var x = T()
var m = U()

}

class T {
var name =someName
}
class U {
var name =someName

$ / code>

var x = T()< - 你认为这是类 T 的一个实例还是泛型?

没有< T> x 要么是一个实例类 - 如果你定义了一个类 T ,或者只是因为该类型没有在任何地方定义



这就是为什么在你看到的实际代码中使用< T> 。实际的类型将进入地点,类型为 T 的地方是之前持有的地方。 :

  func inspect< T> (value1:T,value2:T){
//对value1进行一些操作,value2

var x = T()//错误!
var m = U()//无错误

}

class T {
var name =someName
}
class U {
var name =someName
}

实际上, x = T()会产生一个错误:
$ b


'T'can not因为它没有可访问的初始化器而被构造


如果编译器没有发现这个错误,那么 T 里面的函数将是非泛型的,将来自类定义或只是未知的...



我们做< T> 是为了创建一个本地的vanilla类型,并避免从外面有错误的期望。 (尽管如果你约束它,那么它是不同的)

为什么Swift取代了通用的
T over class T ?我认为这是因为Swift优先考虑本地范围。


func inspect <SomeType> (value: SomeType) {
    print ("Received \(type(of: value)) with the value of \(value)")
}

I am following a tutorial from Pro Swift book, but I can't understand why do we need the <SomeType>. It seems unnecessary. What added information are we giving to the compiler?

The author himself says:

Note the use SomeType: there's one in angle brackets directly after the function name, and one to describe the value parameter. The first one in the angle brackets is the most important, because it defines your placeholder data type: inspect() means "there's a function called inspect() that can be used with any sort of data type, but regardless of what data type is used I want to refer to it as SomeType." So, the parameter value: SomeType should now make more sense: SomeType will be replaced with whatever data type is used to call the function.

I don't get it nor understand what does placeholder data types means?

Edit:
Or with a better example

  func inspect <T> (value1: T, value2: T) {
        // ....
    }

My question: I know that T will enforce value1 & value2 to have same type, so what is the use case of <T>.

解决方案

With credit to both answers provided.

Let's just say you wrote your code as below (without the <T>) and see what happens:

func inspect (value1: T, value2: T) {

    // some operation with value1, value2
}

What is T here? Is T a class? Or it's a generic type as you intended? Just because you wrote something with T it's not going to magically transform into a generic.

To better illustrate the problem see this snippet:

func inspect (value1: T, value2: T) {
    // some operation with value1, value2

    var x = T() 
    var m = U() 

}

class T {
    var name = "someName"
}
class U {
    var name = "someName"
}

var x = T() <-- Do you expect this to be an instance of class T or a generic type?

Without <T>, x would either be an instance class—if you have a class T defined, or just get an error because that type wasn't defined anywhere!


Which is why in real code you see using <T>. The actual type will come into the 'place' where type T was 'holding' onto before. :

func inspect <T> (value1: T, value2: T) {
    // some operation with value1, value2

    var x = T() // error!
    var m = U() // No error

}

class T {
    var name = "someName"
}
class U {
    var name = "someName"
}

Actually doing x = T() creates an error:

'T' cannot be constructed because it has no accessible initializers

If this error wasn't spotted by the compiler then the T inside the function would be non-generic and would come from the class definition or just unknown...

The reason we do‌ <T> is to create a local vanilla type and avoid having wrong expectations from outside. (Though if you constrain it, then it's different)

Why does Swift supersede the generic T over the class T? I assume it's because Swift gives priority to the local scope.

这篇关于什么是占位符?为什么我们需要为泛型定义占位符数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆