为了账号安全,请及时绑定邮箱和手机立即绑定

如何将通用协议用作变量类型

如何将通用协议用作变量类型

浮云间 2019-11-25 15:49:27
假设我有一个协议:public protocol Printable {    typealias T    func Print(val:T)}这是实现class Printer<T> : Printable {    func Print(val: T) {        println(val)    }}我的期望是我必须能够使用Printable变量来打印这样的值:let p:Printable = Printer<Int>()p.Print(67)编译器抱怨此错误:“协议'Printable'只能用作一般约束,因为它具有Self或相关的类型要求”难道我做错了什么 ?有任何解决这个问题的方法吗 ?**EDIT :** Adding similar code that works in C#public interface IPrintable<T> {    void Print(T val);}public class Printer<T> : IPrintable<T>{   public void Print(T val)   {      Console.WriteLine(val);   }}//.... inside Main.....IPrintable<int> p = new Printer<int>();p.Print(67)编辑2:我想要的真实世界的例子。请注意,这不会编译,但会介绍我想要实现的目标。protocol Printable {   func Print()}protocol CollectionType<T where T:Printable> : SequenceType {   .....   /// here goes implementation   ..... }public class Collection<T where T:Printable> : CollectionType<T>{    ......}let col:CollectionType<Int> = SomeFunctiionThatReturnsIntCollection()for item in col {   item.Print()}
查看完整描述

3 回答

?
函数式编程

TA贡献1807条经验 获得超9个赞

解决您的更新用例:


(btw Printable已经是标准的Swift协议,因此您可能希望选择其他名称以避免混淆)


要对协议实现者实施特定的限制,您可以限制协议的类型别名。因此,创建需要元素可打印的协议集合:


// because of how how collections are structured in the Swift std lib,

// you’d first need to create a PrintableGeneratorType, which would be

// a constrained version of GeneratorType

protocol PrintableGeneratorType: GeneratorType {

    // require elements to be printable:

    typealias Element: Printable

}


// then have the collection require a printable generator

protocol PrintableCollectionType: CollectionType {

    typealias Generator: PrintableGenerator

}

现在,如果您想实现一个只能包含可打印元素的集合:


struct MyPrintableCollection<T: Printable>: PrintableCollectionType {

    typealias Generator = IndexingGenerator<T>

    // etc...

}

但是,这可能几乎没有什么实际用途,因为您不能像这样约束现有的Swift集合结构,只能实现它们。


相反,您应该创建通用函数,以将其输入限制为包含可打印元素的集合。


func printCollection

    <C: CollectionType where C.Generator.Element: Printable>

    (source: C) {

        for x in source {

            x.print()

        }

}


查看完整回答
反对 回复 2019-11-25
  • 3 回答
  • 0 关注
  • 615 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信