Swift : Generics
The Problem That Generics Solve
- 省略
Generic Functions
1> func swapThem<T>(inout a: T, inout b: T) {
2. let t = a ;a = b; b = t
3. }
4> var a = 0, b = 2
a: Int = 0
b: Int = 2
5> println("\(a) \(b)")
6. swapThem(&a, &b)
7. println("\(a) \(b)")
0 2
2 0
8> var i = "Apple", j = "Banana"
9> println("\(i) \(j)")
Apple Banana
10> swapThem(&i,&j)
11> println("\(i) \(j)")
Banana Apple
C#:
public class Generic
{
public static void Swap<T>(ref T a , ref T b )
{
var t = a ;
a = b ; b = t;
}
}
var x = 0;
var y = 3;
Console.WriteLine(string.Format("{0} {1}", x, y ));
Generic.Swap(ref x , ref y );
Console.WriteLine(string.Format("{0} {1}", x, y ));
var i = "Apple";
var j = "Banana";
Console.WriteLine(string.Format("{0} {1}", i, j ));
Generic.Swap(ref i , ref j );
Console.WriteLine(string.Format("{0} {1}", i, j ));
0 3
3 0
Apple Banana
Banana Apple
Type Parameters
- "T"のこと
Tが使えるのは
- 引数型
- 返り値型
- 型アノテーション(変数の型宣言)
C#: おなじ
Naming Type Parameters
6> func swapThem<TYPE1>(inout a: TYPE1, inout b: TYPE1) {
7. let t = a ;a = b; b = t
8. }
1> func print<T1, T2>(a : T1, b : T2 ){
2. println("\(a) \(b)")
3. }
C#: 同じ
Generic Types
struct Stack<T> {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
C#: Stack Class
Extending a Generic Type
extension Stack {
var topItem: T? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
C#: Exetnsion Method を定義する
public static class Extensions
{
public static T topItem<T>(this Stack<T> stack)
{
return stack.First ();
}
}
var top = mystack.topItem();
Type Constraints
Type Constraint Syntax
Type Constraints in Action
17> func Employ<T: Person>(person : T)
18. {
19. println("\(person.name) is employed.")
20. }
21> Employ(Student(name:"Bob"))
Bob is employed.
Type Method
16. class Employee : Person {
17. class func employ<T: Person>(p: T) -> Employee
18. {
19. return Employee(name:p.name)
20. }
21. }
22> Employee.employ( Student(name:"Cindy") )
$R0: Employee = {
__lldb_expr_1.Person = {
name = "Cindy"
}
}
C#: where。
public class Company
{
public static Employee Employ<T>(T person) where T: Person
{
return new Employee(){name = person.name};
}
}
var e = Company.Employ(new Student(){name="Bob"});
Console.WriteLine(e.GetType() );
Employee
Associated Types
Associated Type = alias name + Type
An associated type gives a placeholder name (or alias) to a type that is used as part of the protocol.
typealias がキーワード
C#: Associated Type的な物はないと思います
Associated Types in Action
- 要するにGenericの型指定のコンクリートクラスを定義するときに typealias を使えるっぽい
Swift:
protocol Container {
typealias ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct IntStack: Container {
// original IntStack implementation
var items = [Int]()
mutating func push(item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
typealias ItemType = Int
mutating func append(item: Int) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Int {
return items[i]
}
}
C#: Tに型を入れて実装/継承、でいいんじゃないでしょうか。
public interface IContainer<T> {
void append(T item);
int count { get; }
T this[int i] { get; }
}
public class IntStack : IContainer<int>
{
public void append(int item) {}
public int count { get { return 0; }}
public int this[int i] { get { return 0; }}
}
Extending an Existing Type to Specify an Associated Type
Swift: extensionでジェネリックタイプを注入
extension Array: Container {}
C#: Extension メソッドでやるか、継承したサブクラスを定義(ただしクラスは多重継承できない)
Where Clauses
Swift: 型制約に加えて、 whereを使って、Associated Typeの制約を加えられるようです
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
// check that both containers contain the same number of items
if someContainer.count != anotherContainer.count {
return false
}
// check each pair of items to see if they are equivalent
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// all items match, so return true
return true
}
C# Generis
- 型パラメータ制約
- その他...