问题标签 [generic-constraints]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 如何通过 C# 中的反射提取泛型方法约束?
给定一个类型的对象,System.Reflection.MethodInfo
我如何提取通用参数约束?不知何故,我找不到有关此的合理信息。
swift - 可能的错误?我可以创建忽略约束的通用实例
在处理基于节点的框架(包括序列化和反序列化)时,我遇到了一个我可以创建一个忽略类型约束的类的实例的情况。为什么我可以创建一个ZNumericProcessor<String>
内部ZSum
虽然ZNumericProcessor
被定义为不符合ZNumericProcessor<T: ZNumeric>
哪里?为什么它甚至可以调用初始化程序,尽管不确定是否如此?String
ZNumeric
ZSum
T
ZNumeric
通常我会认为我什至不能对 ZSum 的 init 进行约束以使其编译。
第二:如果我在 init 中没有约束ZSum
,我怎么能强制转换,T
以便我可以创建一个实例,ZNumericProcessor
如果我确定它是的话ZNumeric
?
代码:
编辑:阅读此内容后:Stackoverflow Thread我尝试合并它,但尽管提供了限制较少的子类初始化器,但不会被调用(在 ZSum 中)。
编辑 2:更简单的版本,同样的效果,更严格的初始化程序即使使用 String 也会被调用,尽管 String 不是 ZNumeric:
swift - 在 Swift 中限制一个泛型与另一个泛型
我遇到了一个问题,我有一些协议:
该函数bar
是通用的,因为我不希望协议本身具有Self
(它需要在集合中可用)。我有一个协议的实现定义为:
这会产生错误,因为编译器不知道S
并且T
是同一类型。理想情况下,我应该能够编写如下内容:
或者
第一种形式给出了“相同类型的要求使通用参数'S'和'T'等效”错误(这正是我想要做的,所以不知道为什么它是一个错误)。第二种形式给了我一个“继承自非协议、非类类型'S'”。
关于如何使其工作或在 Swift 中更好的设计模式的任何想法?
更新:正如@luk2302 指出的,我忘了Foo
遵守Baz
协议
c# - 接口的通用类型约束?
我可以做这个:
有这样的吗?
我不想明确指定接口名称。
另一种方法是我可以传入一个受约束的参数,class
如果返回 false,则抛出异常typeof(T).IsInterface
,但这不如约束那么干净。
arrays - 无法将协议数组分配给通用数组
下面有一些代码,有些给出编译时错误,有些则没有。这里有错误还是我错过了一些关于泛型的东西?
1)不起作用:
但这有效:
2)不起作用:
但这有效:
3) 这也有效:
T where T: DataType
还有和有什么区别T:DataType
PS:DataType 是一个空协议
c# - C# 分配泛型类型时发出框/拆箱?
我刚刚偶然发现了为以下示例发出的奇怪 IL 代码:
为 Foo 的主体发出的 IL 是
所以我的问题是:为什么它会发出拆箱/装箱操作?我想对话永远不需要任何装箱,因为它要么首先是引用类型,要么是相同的数据类型。
更奇怪的是,即使我明确地说类型参数是引用类型,也不会以任何方式改变发出的代码:
(IL输出相同)
所以为什么?
generics - 如何将 LanguagePrimitives.GenericZero / get_Zero 添加到 System.String?
注意:我在最后添加了很多Of interest
评论。这些并不意味着建议人们应该随意使用它们inline
,它们的存在是为了让人们不必花费数小时搜索与该问题相关的大量 SO 问题来更好地理解这些概念。static type parameters
我知道当需要使函数通用并需要零 (0) 值时,F# 提供GenericZero。
解析为任何原始数值类型或任何具有称为 Zero 的静态成员的类型的零值。
所以这让我相信要使用GenericZero
字符串类型,我只需要添加一个名为 Zero 的静态成员。
由于System.String是 .Net 框架的一部分,因此不应该修改 .Net 源代码。但是 F# 提供类型扩展。
类型扩展允许您将新成员添加到先前定义的对象类型。
F# 还提供了String 模块,但缺少 GenericZero。
有关创建类型扩展的优秀教程,请参考:将函数附加到类型。
我测试的代码:
这是在一个名为Library1
这是在一个名为Workspace
运行时输出:
所以我正在创建和访问扩展成员并使用 GenericZero 没有任何问题。
最后一部分是使用 GenericZero 作为字符串,但是取消注释该行
导致错误:
“字符串”类型不支持运算符“get_Zero”
我确实检查了F# 规范,但没有找到任何帮助。
我可以将 GenericZero 添加到 typeSystem.String
吗,我在代码中做错了什么,还是我错过了文档中的某些内容?
TL;博士
SO搜索时感兴趣的问题
F# - 如何使用 get_Zero 扩展类型,以便可以通用地使用现有类型?
IMO 是一个误导性的标题,应该在阅读答案后更改。
F# 的 int 中的 get_Zero 是什么/在哪里?
杰克有一个很好的评论:
如果您从数字的角度来考虑,零在字符串上没有意义;但是,在返回空字符串的字符串上有一个 Zero 成员确实有意义,因为这会使字符串在字符串连接下成为一个幺半群。
感兴趣的 F# 文档
F# 编译器在对函数执行类型推断时,会确定给定参数是否可以是泛型的。编译器检查每个参数并确定函数是否依赖于该参数的特定类型。如果不是,则类型被推断为泛型。
类型推断的想法是,您不必指定 F# 构造的类型,除非编译器无法最终推断出类型。
对于那些没有明确指定的类型,编译器会根据上下文推断类型。如果没有另外指定类型,则推断为泛型。
F# 函数值、方法、属性和聚合类型(例如类、记录和可区分联合)可以是通用的。泛型构造包含至少一个类型参数,通常由泛型构造的用户提供。泛型函数和类型使您能够编写适用于各种类型的代码,而无需为每种类型重复代码。在 F# 中使您的代码通用化可能很简单,因为编译器的类型推断和自动泛化机制通常会隐式推断您的代码是通用的。
静态解析类型参数是在编译时而不是在运行时替换为实际类型的类型参数。它们前面有一个插入符号 (^)。
静态解析的类型参数主要与成员约束结合使用,成员约束是允许您指定类型参数必须具有特定成员或成员才能使用的约束。没有办法通过使用常规泛型类型参数来创建这种约束。
在 F# 语言中,有两种不同的类型参数。第一种是标准的泛型类型参数。这些用撇号 (') 表示,如 'T 和 'U。它们等效于其他 .NET Framework 语言中的泛型类型参数。另一种是静态解析的,由插入符号表示,如 ^T 和 ^U。
当您使用静态类型参数时,任何由类型参数参数化的函数都必须是 inline。
编辑
这是一个示例,它GenericZero
用于用户定义的类型,而不使用有效的扩展名和两个显示GenericZero
不适用的变体intrinsic extension
和optional extension
首先运行程序以查看GenericZero
工作,然后取消注释中的行Program.fs
以查看 和 的intrinsic extension
错误optional extension
。
内在扩展是与被扩展的类型出现在同一命名空间或模块、同一源文件和同一程序集(DLL 或可执行文件)中的扩展。
可选扩展是出现在被扩展类型的原始模块、命名空间或程序集之外的扩展。当通过反射检查类型时,类型上会出现内在扩展,但可选扩展不会。可选扩展必须在模块中,并且仅当包含扩展的模块打开时它们才在范围内。
在Library1.fs
项目中Library1
在Library2.fs
项目中Library2
在Program.fs
项目中Workspace
swift - 快速模式匹配
在下面的代码中:
如果在
(所有者 var 定义为[Serializable]
)
case let value as Array<Serializable>:
会识别它,但以防万一:
(所有者 var 定义为[Owner]
)
case let value as Array<Serializable>:
不会识别它,虽然Owner
符合Serializable
协议?有人可以解释为什么吗?
我试过了:
有效,所以 Swift 认识到[Owner]
,[Serializable]
为什么case let value as Array<Serializable>
匹配[Serializable]
但不匹配[Owner]
?
java - 为什么接口的泛型方法可以在 Java 中实现为非泛型?
假设我们有一些这样的测试接口/类:
你可以看到Animal.eat
是一个带有约束的泛型方法。现在我的Human
课是这样的:
编译得很好。您可以看到,由于接口丢失,因此受到的Human.eat
限制更少。Animal.eat
Eatable
Q1:为什么编译器不抱怨这种不一致?
Q2:如果编译器可以接受Plant&Eatable
降级,为什么会抱怨?Plant
eat(Object plant)
c# - 避免显式泛型类型 c#
假设我有一个泛型class
,它有一个约束 where T
must implement IWatchable<TKey>
,那么有没有什么方法可以使用,Watcher
而不必显式声明TKey
类型,考虑到T
无论如何都会提供它?
如果我想使用,无论如何Watcher
class
我都必须将其声明TKey
为第二种类型。
或者