我有一个快速的功能,让我们称之为functionMakingMeUnhappy
。 T
会返回T
类型,其中SomeProtocol
属于func functionMakingMeUnhappy<T:SomeProtocol>(meta: Metadata, value: Any, name: String) -> T
{
// Do some stuff and then return something as! T
return returnSomeStuff(meta, value: value, name: name) as! T
}
类型。
定义如下:
public struct Metadata
{
var someUniqueIdentifier: String
var someOtherUniqueIdentifier: String
var someTypeIdentifier: String
var somePermission: String
var someOtherProperties = [String: Any]()
init(someUniqueIdentifier: String,
someOtherUniqueIdentifier: String,
someTypeIdentifier: String,
somePermission: String,
someOtherProperties: [String: AnyObject])
{
self.someUniqueIdentifier = someUniqueIdentifier
self.someOtherUniqueIdentifier = someOtherUniqueIdentifier
self.someTypeIdentifier = someTypeIdentifier
self.somePermission = somePermission
self.someOtherProperties = someOtherProperties
}
}
如果它有用,Metadata就是这样的结构:
functionMakingMeUnhappy
现在,我的问题,虽然听起来很愚蠢,但是当我使用与函数定义完全相同的参数类型调用var data = Metadata(someUniqueIdentifier: "id",
someOtherUniqueIdentifier: "charType",
someTypeIdentifier: "type",
somePermission: "readonly",
someOtherProperties: [:]
)
var unhappy = functionMakingMeUnhappy(data, value: "someValue", name: "someName")
时,我收到一条错误,指出无法调用functionMakingMeUnhappy类型的参数列表&#39;(元数据,值:任意,名称:字符串)&#39;
电话如下:
private string MyDUIDSql(string pSPID)
{
PATH1PRDDataContext path1prd = new PATH1PRDDataContext();
var query = from sampleunits in path1prd.TBLSAMPLEUNITs
where sampleunits.PROJECTSUID == pSPID && sampleunits.AssignmentTypeID < 19
select sampleunits.DUID;
return query.Single();
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="WindowsFormsApplication1.Properties.Settings.PATH1PRDConnectionString"
connectionString="Data Source=PATHSQL;Initial Catalog=PATH1PRD;Persist Security Info=True;User ID=********;Password=******"
providerName="System.Data.SqlClient" />
<add name="WindowsFormsApplication1.Properties.Settings.PATHBaseline_BESConnectionString"
connectionString="Data Source=PATHSQL;Initial Catalog=PATHBaseline_BES;Persist Security Info=True;User ID=******;Password=************"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
在使用可能导致此错误的通用函数时是否有任何要求?
答案 0 :(得分:1)
听起来好像你不明白通用是什么。尽管有这个名字,但是泛型不是通用的 - 它们不是某种神奇的东西。相反,泛型是一种必须在编译时专门知道的类型。这称为 resolution (或规范)。
好吧,你在functionMakingMeUnhappy
的电话中没有做任何可以解决通用问题的事情。请考虑以下非常简化的代码版本:
protocol P{}
class C:P{}
func f<T:P>() -> T {
return C() as! T
}
var v = f() // error
对f()
的调用没有任何内容可以告诉编译器T是什么。因此它不会编译。我承认错误消息具有误导性,但事实是该错误的源。 T仅作为返回类型出现。但你没有说回归类型。
现在这样做:
protocol P{}
class C:P{}
func f<T:P>() -> T {
return C() as! T
}
var v : C = f() // ok
编译。为什么?因为现在我们已经做了一些事情来告诉编译器f
的返回类型是什么。因此T得到了解决。
(请注意,我甚至没有触及你关于为什么你使这个功能成为通用的奇怪主张。我只是回答你问的直接问题,也就是说,为什么你的代码如图所示不能编译。)