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

假设我有一个协议:


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()

}


浮云间
浏览 616回答 3
3回答

函数式编程

解决您的更新用例:(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 GeneratorTypeprotocol PrintableGeneratorType: GeneratorType {&nbsp; &nbsp; // require elements to be printable:&nbsp; &nbsp; typealias Element: Printable}// then have the collection require a printable generatorprotocol PrintableCollectionType: CollectionType {&nbsp; &nbsp; typealias Generator: PrintableGenerator}现在,如果您想实现一个只能包含可打印元素的集合:struct MyPrintableCollection<T: Printable>: PrintableCollectionType {&nbsp; &nbsp; typealias Generator = IndexingGenerator<T>&nbsp; &nbsp; // etc...}但是,这可能几乎没有什么实际用途,因为您不能像这样约束现有的Swift集合结构,只能实现它们。相反,您应该创建通用函数,以将其输入限制为包含可打印元素的集合。func printCollection&nbsp; &nbsp; <C: CollectionType where C.Generator.Element: Printable>&nbsp; &nbsp; (source: C) {&nbsp; &nbsp; &nbsp; &nbsp; for x in source {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x.print()&nbsp; &nbsp; &nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP