Can I specify that a generic is a value type?

后端 未结 2 1480
执念已碎
执念已碎 2021-02-07 06:20

I know that we can essentially specify that our generics be any reference type by using AnyObject:

class Foo {
    // ...
}
         


        
2条回答
  •  轮回少年
    2021-02-07 07:18

    A possible way if it is enough for you to use Assertion:

    public final class Synchronized {
        private var _value: T        
            
        public init(_ value: T) {
           assert(!isReferenceType(value))
           _value = value
        }
        ...
    }
        
    func isReferenceType(_ any: Any) -> Bool {
        return Mirror(reflecting: any).displayStyle == .class
    }
    

    Some Unit Tests to prove it works as expected:

    import XCTest
    
    final class SynchronizedTests: XCTestCase {
        class FakeClass {}
        struct FakeStruct {}
        enum FakeEnum {
            case first
        }
    
        func testIsReferenceType() {
            XCTAssert(isReferenceType(FakeClass()))
    
            XCTAssertFalse(isReferenceType(FakeStruct()))
            XCTAssertFalse(isReferenceType(FakeEnum.first))
            XCTAssertFalse(isReferenceType("string"))
            XCTAssertFalse(isReferenceType(123))
            XCTAssertFalse(isReferenceType(123.4))
            XCTAssertFalse(isReferenceType([1, 2, 3]))
            XCTAssertFalse(isReferenceType(Set([1, 2, 3])))
            XCTAssertFalse(isReferenceType(["1": 1, "2": 2, "3": 3]))
        }
    }
    

提交回复
热议问题