> Am 11.06.2016 um 13:22 schrieb Jonathan Hull via swift-evolution 
> <[email protected]>:
> 
> Here is another example from a current project: (Here there is an option to 
> trap, if desired… but many more options not to)
> (Note: The commented out bit was an attempt to get the compiler to play nicer 
> with intuiting the type, but it didn’t help… leaving as data)
> 
> struct HashableBox:Hashable {
>     private let _value:Any
>     private let _hash:Int
>     private let _eq:(Any)->Bool
>     
>     enum Error:ErrorType {
>         case typeMismatch
>     }
>     
>     init<T:Hashable>(_ value:T){
>         self._value = value
>         self._hash = value.hashValue
>         self._eq = { other in
>             guard let otherT = other as? T else {return false}
>             return value == otherT
>         }
>     }

I think there is an error in the implementation of _eq, because it should try 
to unpack the value as T and not the box.

HashableBox(1) == HashableBox(1) should be true IMO but is false with your 
implementation

This works as I would expect:

    private let _eq:(HashableBox)->Bool

    init<T:Hashable>(_ value:T){
        self._value = value
        self._hash = value.hashValue
        self._eq = { other in
            guard let otherValue: T = other.valueOrNil() else { return false }
            return value == otherValue
        }
    }

-Thorsten


>     
>     func valueOrCrash<T:Hashable>(msg:String? = nil) -> T {
>         guard let value = _value as? T else {
>             let msg = msg ?? "Attempt to retrieve value of type 
> \(self._value.dynamicType) as \(T.self)"
>             fatalError(msg)
>         }
>         return value
>     }
>     
>     func valueOrNil<T:Hashable>() -> T? {//(type:T.Type = T.self) -> T? {
>         return self._value as? T
>     }
>     
>     func valueOrError<T:Hashable>()throws -> T {
>         guard let value = _value as? T else {throw Error.typeMismatch}
>         return value
>     }
>     
>     var asAny:Any {
>         return _value
>     }
>     
>     var hashValue: Int {
>         return _hash
>     }
> }
> 
> func == (lhs:HashableBox, rhs:HashableBox) -> Bool {
>     return lhs._eq(rhs)
> }
> 
> 
> Thanks,
> Jon
> 
>> On Jun 11, 2016, at 3:25 AM, Jonathan Hull <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> 
>>> If your code has many manual type erasing wrappers corresponding to
>>> protocols with associated types and/or Self requirements that also never
>>> have to trap type mismatches, that would certainly be instructive
>>> empirical data.  Would you care to share the protocols and wrappers you
>>> are talking about?
>> This code is a bit embarrassing (I wrote most of it as I was still learning 
>> Swift), but if it is helpful I will share:
>> https://gist.github.com/jonhull/639e756ad5228348f93f40f06169588c 
>> <https://gist.github.com/jonhull/639e756ad5228348f93f40f06169588c>
>> 
>> It doesn’t trap anywhere (that I know about). Some of the code which calls 
>> it does throw an error in the case of mismatched types (but it 
>> doesn’t/shouldn't crash).  Most functions which use it are generic on the 
>> associatedType.
>> 
>> It does work fairly well though (even on the AppleWatch).  The main issue is 
>> that I have no way to persist the values which have been drawn into the 
>> type-erased world (or even the value-type world, really).
>> 
>> Also, if anyone has a better way to write the type erasing wrapper, I would 
>> love to hear it. These are very memory intensive…
>> 
>> Thanks,
>> Jon
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to