Create a Weak Container in Swift That Accepts a Native Swift Protocol

Create a weak container in Swift that accepts a native Swift protocol

If you are fine with losing some compile time safety, you can change your Weak to accept Any as T and then store value as AnyObject:

struct Weak<T: Any>{
weak var value: AnyObject?

public var ref: T? {
get {
return value as? T
}
}

init(value: T) {
self.value = value as AnyObject
}
}

Swift confine protocol to certain types of class only

What you want is a subclass

class SKSceneWithProtocol : SKScene, GameSceneProtocol

but at this point the protocol is essentially pointless, and you may as well just do the code in the subclass instead.

Your other option is to cast the scene to the protocol when you need to use it

if let sceneProtocol = scene as? GameSceneProtocol
{
//do stuff here
}

How to implement a Swift protocol across structs with conflicting property names

The desired feature from explicit interface implementations is that they are statically dispatched, right? If you use Description on a BusStop, it will be an optional string, but if you use Description on a Stop, it will be a non-optional string.

In Swift, extension members are statically dispatched, so you can make use of this to achieve something similar:

extension Stop where Self == BusStop {
// Since the type of "self" here is BusStop, "Description" refers to the one declared in BusStop
// not this one here, so this won't cause infinite recursion
var Description : String { return self.Description ?? "" }
}

extension Stop where Self == TrainStop {
var Latitude: Double { return self.Latitude ?? 0 }
var Longitude: Double { return self.Longitude ?? 0 }
}

This code shows that this works:

let busStop = BusStop(Code: "ABC", Description: "My Bus Stop", Latitude: 0, Longitude: 0)
print(type(of: busStop.Description)) // Optional<String>
let stop: Stop = busStop
print(type(of: stop.Description)) // String

However, I still don't think this is good Swift code. It is often bad to just directly translate an API from one language to another. If I were you, I would make Longitude, Latitude and Description in Stop to be all optionals.

Conditionally conform Set to ExpressibleByDictionaryLiteral protocol

You simply need to make the Weighted protocol public as well as marking the init public.

public protocol Weighted: Hashable {
associatedtype D: Hashable
associatedtype W: Hashable
var destination: D { get }
var weight: W { get }
init(destination: D, weight: W)
}

extension Set: ExpressibleByDictionaryLiteral where Element: Weighted {
public init(dictionaryLiteral elements: (Element.D, Element.W)...) {
self.init(elements.map(Element.init))
}
}

Self in protocol

Self.Element refers to the concrete type that any type implementing GeneratorType protocol will declare as its Element typealias.

For example, in this generator of Fibonacci numbers:

struct Fibonacci: GeneratorType {
typealias Element = Int

private var value: Int = 1
private var previous: Int = 0

mutating func next() -> Element? {
let newValue = value + previous

previous = value
value = newValue

return previous
}
}

... you implement GeneratorType protocol and indicate what will be its Element typealias (Int in this case), and that's the type that generator's next() will be returning (well, actually the optional of that type).

Quite often, though, you would not have to explicitly specify typealiases when implementing parametrised protocols, as Swift is smart enough to infer them for you. E.g. for the Fibonacci numbers generator from the above example the following will also do:

struct Fibonacci: GeneratorType {
private var value: Int = 1
private var previous: Int = 0

mutating func next() -> Int? {
let newValue = value + previous

previous = value
value = newValue

return previous
}
}

... Swift knows from the signature of next() that it returns Int?, and that GeneratorType implementors also must have next() in their to-do list, and that these methods must return Element? types. So, Swift just puts 2 and 2 together, and infers that Element? must be the same thing as Int?, and therefore Element == Int.


About this:

public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public init(_ elements: Elements)
public mutating func next() -> Elements._Element?
}

Here we have four things going on:

  • We declare generic type IndexingGenerator that takes a parameter-type called Elements.
  • This Elements type has a constraint that it must implement Indexable protocol.
  • The generator that we implement is supposed to return values of the type that is accessible via Indexable interface of Elements, which is known to IndexingGenerator via dot-syntax as Elements._Element.
  • Swift infers that Element of IndexingGenerator is the same thing as Elements._Element.

So, essentially the above delclaration is equivalent to:

public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public typealias Element = Elements._Element
public init(_ elements: Elements)
public mutating func next() -> Element?
}

Finally, if curious why _Element and not just Element like in GeneratorType, here is what they write in the open-source Swift repository (under swift/stdlib/public/core/Collection.swift):

The declaration of _Element and subscript here is a trick used to break a cyclic conformance/deduction that Swift can't handle. We need something other than a CollectionType.Generator.Element that can be used as IndexingGenerator<T>'s Element. Here we arrange for the CollectionType itself to have an Element type that's deducible from its subscript. Ideally we'd like to constrain this Element to be the same as CollectionType.Generator.Element, but we have no way of expressing it today.

Swift Function Input Generic Conform To Both Class And Protocol

Not a direct answer to your question but all you need is to add an enumeration to store the kind of measurement to your class, and a computed property to return the corresponding dictionary. No need to use a protocol, protocol composition, class and/or subclass to accomplish what you are trying to do:

struct AMeasurement {
let imperial: Double
let metric: Double
let kind: Kind
enum Kind { case distance, steps }
var units: [String: String] {
switch kind {
case .distance: return ["imperial": "miles", "metric":"kms"]
case .steps: return ["imperial": "steps", "metric":"steps"]
}
}
}


extension AMeasurement {
func printValues() {
print("\(imperial) \(units["imperial"]!) = \(metric) \(units["metric"]!)")
}
}


let distance = AMeasurement(imperial: 30, metric: 48.28, kind: .distance)
let steps = AMeasurement(imperial: 30, metric: 30, kind: .steps)
let types = [distance, steps]

for type in types {
type.printValues()
}

30.0 miles = 48.28 kms

30.0 steps = 30.0 steps

Swinject: Using weak scope is leaking objects

There is no memory leak, it's just a bug in Xcode 8 memory profiling instruments. See discussing at GitHub issues tracker

Sample Image



Related Topics



Leave a reply



Submit