What is equivalent for C# or Java generic interface in Swift?How can I design a generic observer pattern protocol in Swift?How can I use Type Erasure with a protocol using associated typeWhat does an exclamation mark mean in the Swift language?What is the Swift equivalent of isEqualToString in Objective-C?What is the Swift equivalent of respondsToSelector?Write a Generator to custom dictionary class in Swift with Genericsswift how to define abstract class and why apple invent associated type but not use generic protocolUse of typealias syntax within protocols in the Swift standard librarySwift generic Type inheriting from another generic typeSwift-Generics: “Cannot specialize non-generic type”swift convenience init and generic classSwift Mediator Pattern - Collection of generic protocols
Which is the best password hashing algorithm in .NET Core?
How could a planet have one hemisphere way warmer than the other without the planet being tidally locked?
How to find better food in airports
What would a biological creature need in order to see the future?
How do I stop making people jump at home and at work?
Can there be plants on the dark side of a tidally locked world?
Main differences between 5th edition Druid and 3.5 edition Druid
If p-value is exactly 1 (1.0000000), what are the confidence interval limits?
Finder/Terminal: Find files that contain less than 21 lines of text
Do 643,000 Americans go bankrupt every year due to medical bills?
Are there photos of the Apollo LM showing disturbed lunar soil resulting from descent engine exhaust?
Do index funds really have double-digit percents annual return rates?
Is Levitate supposed to basically disable a melee based enemy?
'Hard work never hurt anyone' Why not 'hurts'?
One hour 10 min layover in Newark; International -> Domestic connection. Enough time to clear customs?
Tiny image scraper for xkcd.com
Does POSIX guarantee the paths to any standard utilities?
When making yogurt, why doesn't bad bacteria grow as well?
Why don't they build airplanes from 3D printer plastic?
Do mortgage points get applied directly to the principal?
Punishment in pacifist society
Planet that’s 90% water or more?
Can a country avoid prosecution for crimes against humanity by denying it happened?
Is there any reason to change the ISO manually?
What is equivalent for C# or Java generic interface in Swift?
How can I design a generic observer pattern protocol in Swift?How can I use Type Erasure with a protocol using associated typeWhat does an exclamation mark mean in the Swift language?What is the Swift equivalent of isEqualToString in Objective-C?What is the Swift equivalent of respondsToSelector?Write a Generator to custom dictionary class in Swift with Genericsswift how to define abstract class and why apple invent associated type but not use generic protocolUse of typealias syntax within protocols in the Swift standard librarySwift generic Type inheriting from another generic typeSwift-Generics: “Cannot specialize non-generic type”swift convenience init and generic classSwift Mediator Pattern - Collection of generic protocols
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I am Swift newcomer from C#. I started designing the Swift program from the abstract level - declaring entities signatures with relationships between them. I caught that protocol in swift is analog of the interface in C# or Java. From my (as Swift newcomer from C#) point of view, generics in protocols implemented in Swift by an uncommon way. I researched about associated types but continuously didn't know how to do the following:
typealias Observer<T> = (T) -> ()
protocol Subscription
func cancel()
protocol Observable<T>
func subscribe(observer: Observer<T>) -> Subscription
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
The code above is from the imaginary world where generic protocols have the same struct as generic classes. Is it possible to write the code above compilable by associated types using? How? If it is impossible, what is an alternative?
Remark 1
I need described architecture to provide something like the following:
class First: AbcObservable ...
class Second: AbcObservable ...
class Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
class IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(abc)
class Mock: AbcObservable ...
class Test
func test()
let abcMock = Mock()
let client = Client(abcMock)
...
This moment is very painfully for me; I can't understand how I can provide D of SOLID in my code in the case when I need generics.
Remark 2
Observable will not have many implementations in the real situation and it is stupid to do it as abstract. I wanted to write the essence of my problem, and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations.
Remark 3
The question was changed from "How to use protocol with associatedtype in another protocol?" to "What is equivalent for C# or Java generic interface in Swift?"
swift
|
show 2 more comments
I am Swift newcomer from C#. I started designing the Swift program from the abstract level - declaring entities signatures with relationships between them. I caught that protocol in swift is analog of the interface in C# or Java. From my (as Swift newcomer from C#) point of view, generics in protocols implemented in Swift by an uncommon way. I researched about associated types but continuously didn't know how to do the following:
typealias Observer<T> = (T) -> ()
protocol Subscription
func cancel()
protocol Observable<T>
func subscribe(observer: Observer<T>) -> Subscription
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
The code above is from the imaginary world where generic protocols have the same struct as generic classes. Is it possible to write the code above compilable by associated types using? How? If it is impossible, what is an alternative?
Remark 1
I need described architecture to provide something like the following:
class First: AbcObservable ...
class Second: AbcObservable ...
class Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
class IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(abc)
class Mock: AbcObservable ...
class Test
func test()
let abcMock = Mock()
let client = Client(abcMock)
...
This moment is very painfully for me; I can't understand how I can provide D of SOLID in my code in the case when I need generics.
Remark 2
Observable will not have many implementations in the real situation and it is stupid to do it as abstract. I wanted to write the essence of my problem, and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations.
Remark 3
The question was changed from "How to use protocol with associatedtype in another protocol?" to "What is equivalent for C# or Java generic interface in Swift?"
swift
Might be useful to watch developer.apple.com/videos/play/wwdc2018/406
– matt
Mar 28 at 0:03
1
All the answers I want to type here look like "stop stop stop stop stop stop." Do not start with abstract inversion of control. Start with a goal in mind for your software, and from there, extract generic solutions. There are way, way too many protocols here, and they look like they're just trying to stand-in for abstract classes maybe? Protocols are not abstract classes. They're not about inheritance. They're about extension. What actual thing do you want this for? From that, we can design often very elegant solutions (not every time, but often).
– Rob Napier
Mar 28 at 1:27
If you're interested in building observables, take a look at github.com/davedelong/Syzygy/tree/master/SyzygyCore/Properties for one fairly powerful approach (while being much smaller than RxSwift, which is a much more powerful approach). Or you can start with an even simpler model that I use, and is probably much easier to understand: gist.github.com/rnapier/981e86fbf345b049c1df41f63e4a2c6e
– Rob Napier
Mar 28 at 1:31
1
"I caught that protocol in swift is analog of the interface in C# or Java." This is probably the heart of your mistake. This isn't a really great analogy. They're not unrelated, but the use of protocols is very different, particularly protocols w/ associated types (what you're thinking of as "generic protocols"). They're definitely not the tool to start with in Swift. They will generally arise out of code where you find duplication, rather than being something you start with.
– Rob Napier
Mar 28 at 1:34
If you're looking for IoC patterns in Swift, see stackoverflow.com/a/55368056/97337 for an example (at the bottom of the answer, not the type-eraser part at the top)
– Rob Napier
Mar 28 at 1:53
|
show 2 more comments
I am Swift newcomer from C#. I started designing the Swift program from the abstract level - declaring entities signatures with relationships between them. I caught that protocol in swift is analog of the interface in C# or Java. From my (as Swift newcomer from C#) point of view, generics in protocols implemented in Swift by an uncommon way. I researched about associated types but continuously didn't know how to do the following:
typealias Observer<T> = (T) -> ()
protocol Subscription
func cancel()
protocol Observable<T>
func subscribe(observer: Observer<T>) -> Subscription
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
The code above is from the imaginary world where generic protocols have the same struct as generic classes. Is it possible to write the code above compilable by associated types using? How? If it is impossible, what is an alternative?
Remark 1
I need described architecture to provide something like the following:
class First: AbcObservable ...
class Second: AbcObservable ...
class Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
class IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(abc)
class Mock: AbcObservable ...
class Test
func test()
let abcMock = Mock()
let client = Client(abcMock)
...
This moment is very painfully for me; I can't understand how I can provide D of SOLID in my code in the case when I need generics.
Remark 2
Observable will not have many implementations in the real situation and it is stupid to do it as abstract. I wanted to write the essence of my problem, and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations.
Remark 3
The question was changed from "How to use protocol with associatedtype in another protocol?" to "What is equivalent for C# or Java generic interface in Swift?"
swift
I am Swift newcomer from C#. I started designing the Swift program from the abstract level - declaring entities signatures with relationships between them. I caught that protocol in swift is analog of the interface in C# or Java. From my (as Swift newcomer from C#) point of view, generics in protocols implemented in Swift by an uncommon way. I researched about associated types but continuously didn't know how to do the following:
typealias Observer<T> = (T) -> ()
protocol Subscription
func cancel()
protocol Observable<T>
func subscribe(observer: Observer<T>) -> Subscription
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
The code above is from the imaginary world where generic protocols have the same struct as generic classes. Is it possible to write the code above compilable by associated types using? How? If it is impossible, what is an alternative?
Remark 1
I need described architecture to provide something like the following:
class First: AbcObservable ...
class Second: AbcObservable ...
class Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
class IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(abc)
class Mock: AbcObservable ...
class Test
func test()
let abcMock = Mock()
let client = Client(abcMock)
...
This moment is very painfully for me; I can't understand how I can provide D of SOLID in my code in the case when I need generics.
Remark 2
Observable will not have many implementations in the real situation and it is stupid to do it as abstract. I wanted to write the essence of my problem, and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations.
Remark 3
The question was changed from "How to use protocol with associatedtype in another protocol?" to "What is equivalent for C# or Java generic interface in Swift?"
swift
swift
edited Mar 28 at 3:21
Valentine Zakharenko
asked Mar 27 at 23:55
Valentine ZakharenkoValentine Zakharenko
1,0411 gold badge9 silver badges29 bronze badges
1,0411 gold badge9 silver badges29 bronze badges
Might be useful to watch developer.apple.com/videos/play/wwdc2018/406
– matt
Mar 28 at 0:03
1
All the answers I want to type here look like "stop stop stop stop stop stop." Do not start with abstract inversion of control. Start with a goal in mind for your software, and from there, extract generic solutions. There are way, way too many protocols here, and they look like they're just trying to stand-in for abstract classes maybe? Protocols are not abstract classes. They're not about inheritance. They're about extension. What actual thing do you want this for? From that, we can design often very elegant solutions (not every time, but often).
– Rob Napier
Mar 28 at 1:27
If you're interested in building observables, take a look at github.com/davedelong/Syzygy/tree/master/SyzygyCore/Properties for one fairly powerful approach (while being much smaller than RxSwift, which is a much more powerful approach). Or you can start with an even simpler model that I use, and is probably much easier to understand: gist.github.com/rnapier/981e86fbf345b049c1df41f63e4a2c6e
– Rob Napier
Mar 28 at 1:31
1
"I caught that protocol in swift is analog of the interface in C# or Java." This is probably the heart of your mistake. This isn't a really great analogy. They're not unrelated, but the use of protocols is very different, particularly protocols w/ associated types (what you're thinking of as "generic protocols"). They're definitely not the tool to start with in Swift. They will generally arise out of code where you find duplication, rather than being something you start with.
– Rob Napier
Mar 28 at 1:34
If you're looking for IoC patterns in Swift, see stackoverflow.com/a/55368056/97337 for an example (at the bottom of the answer, not the type-eraser part at the top)
– Rob Napier
Mar 28 at 1:53
|
show 2 more comments
Might be useful to watch developer.apple.com/videos/play/wwdc2018/406
– matt
Mar 28 at 0:03
1
All the answers I want to type here look like "stop stop stop stop stop stop." Do not start with abstract inversion of control. Start with a goal in mind for your software, and from there, extract generic solutions. There are way, way too many protocols here, and they look like they're just trying to stand-in for abstract classes maybe? Protocols are not abstract classes. They're not about inheritance. They're about extension. What actual thing do you want this for? From that, we can design often very elegant solutions (not every time, but often).
– Rob Napier
Mar 28 at 1:27
If you're interested in building observables, take a look at github.com/davedelong/Syzygy/tree/master/SyzygyCore/Properties for one fairly powerful approach (while being much smaller than RxSwift, which is a much more powerful approach). Or you can start with an even simpler model that I use, and is probably much easier to understand: gist.github.com/rnapier/981e86fbf345b049c1df41f63e4a2c6e
– Rob Napier
Mar 28 at 1:31
1
"I caught that protocol in swift is analog of the interface in C# or Java." This is probably the heart of your mistake. This isn't a really great analogy. They're not unrelated, but the use of protocols is very different, particularly protocols w/ associated types (what you're thinking of as "generic protocols"). They're definitely not the tool to start with in Swift. They will generally arise out of code where you find duplication, rather than being something you start with.
– Rob Napier
Mar 28 at 1:34
If you're looking for IoC patterns in Swift, see stackoverflow.com/a/55368056/97337 for an example (at the bottom of the answer, not the type-eraser part at the top)
– Rob Napier
Mar 28 at 1:53
Might be useful to watch developer.apple.com/videos/play/wwdc2018/406
– matt
Mar 28 at 0:03
Might be useful to watch developer.apple.com/videos/play/wwdc2018/406
– matt
Mar 28 at 0:03
1
1
All the answers I want to type here look like "stop stop stop stop stop stop." Do not start with abstract inversion of control. Start with a goal in mind for your software, and from there, extract generic solutions. There are way, way too many protocols here, and they look like they're just trying to stand-in for abstract classes maybe? Protocols are not abstract classes. They're not about inheritance. They're about extension. What actual thing do you want this for? From that, we can design often very elegant solutions (not every time, but often).
– Rob Napier
Mar 28 at 1:27
All the answers I want to type here look like "stop stop stop stop stop stop." Do not start with abstract inversion of control. Start with a goal in mind for your software, and from there, extract generic solutions. There are way, way too many protocols here, and they look like they're just trying to stand-in for abstract classes maybe? Protocols are not abstract classes. They're not about inheritance. They're about extension. What actual thing do you want this for? From that, we can design often very elegant solutions (not every time, but often).
– Rob Napier
Mar 28 at 1:27
If you're interested in building observables, take a look at github.com/davedelong/Syzygy/tree/master/SyzygyCore/Properties for one fairly powerful approach (while being much smaller than RxSwift, which is a much more powerful approach). Or you can start with an even simpler model that I use, and is probably much easier to understand: gist.github.com/rnapier/981e86fbf345b049c1df41f63e4a2c6e
– Rob Napier
Mar 28 at 1:31
If you're interested in building observables, take a look at github.com/davedelong/Syzygy/tree/master/SyzygyCore/Properties for one fairly powerful approach (while being much smaller than RxSwift, which is a much more powerful approach). Or you can start with an even simpler model that I use, and is probably much easier to understand: gist.github.com/rnapier/981e86fbf345b049c1df41f63e4a2c6e
– Rob Napier
Mar 28 at 1:31
1
1
"I caught that protocol in swift is analog of the interface in C# or Java." This is probably the heart of your mistake. This isn't a really great analogy. They're not unrelated, but the use of protocols is very different, particularly protocols w/ associated types (what you're thinking of as "generic protocols"). They're definitely not the tool to start with in Swift. They will generally arise out of code where you find duplication, rather than being something you start with.
– Rob Napier
Mar 28 at 1:34
"I caught that protocol in swift is analog of the interface in C# or Java." This is probably the heart of your mistake. This isn't a really great analogy. They're not unrelated, but the use of protocols is very different, particularly protocols w/ associated types (what you're thinking of as "generic protocols"). They're definitely not the tool to start with in Swift. They will generally arise out of code where you find duplication, rather than being something you start with.
– Rob Napier
Mar 28 at 1:34
If you're looking for IoC patterns in Swift, see stackoverflow.com/a/55368056/97337 for an example (at the bottom of the answer, not the type-eraser part at the top)
– Rob Napier
Mar 28 at 1:53
If you're looking for IoC patterns in Swift, see stackoverflow.com/a/55368056/97337 for an example (at the bottom of the answer, not the type-eraser part at the top)
– Rob Napier
Mar 28 at 1:53
|
show 2 more comments
1 Answer
1
active
oldest
votes
You've overused protocols here, but this is the syntax you'd want. Several of these pieces can't reasonably be protocols. I have trouble imagining three different implementations of Observable, and certainly not of Subscription. (If you can't imagine three implementations, it's probably not a protocol.) Trying to make Observable into a protocol definitely causes the whole thing to explode.
Subscription is just a wrapper around a function, so that's struct. Observable is naturally a class. The rest is possibly fine; your problems there are mostly syntax.
import Foundation
typealias Observer<T> = (T) -> ()
struct Subscription
let cancel: () -> Void
final class Observable<T>
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: [weak self] in self?.observations[uuid] = nil )
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
struct First: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Second: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
struct IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(lightDependency: abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(lightDependency: abc)
struct Mock: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
class Test
func test()
let abcMock = Mock()
let client = Client(lightDependency: abcMock)
The Observer implementation here is based on my Subject implementation. Note that this is part of a system that has several quirks that I don't love (Dave Delong's Syzygy is better).
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388214%2fwhat-is-equivalent-for-c-sharp-or-java-generic-interface-in-swift%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You've overused protocols here, but this is the syntax you'd want. Several of these pieces can't reasonably be protocols. I have trouble imagining three different implementations of Observable, and certainly not of Subscription. (If you can't imagine three implementations, it's probably not a protocol.) Trying to make Observable into a protocol definitely causes the whole thing to explode.
Subscription is just a wrapper around a function, so that's struct. Observable is naturally a class. The rest is possibly fine; your problems there are mostly syntax.
import Foundation
typealias Observer<T> = (T) -> ()
struct Subscription
let cancel: () -> Void
final class Observable<T>
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: [weak self] in self?.observations[uuid] = nil )
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
struct First: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Second: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
struct IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(lightDependency: abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(lightDependency: abc)
struct Mock: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
class Test
func test()
let abcMock = Mock()
let client = Client(lightDependency: abcMock)
The Observer implementation here is based on my Subject implementation. Note that this is part of a system that has several quirks that I don't love (Dave Delong's Syzygy is better).
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
add a comment |
You've overused protocols here, but this is the syntax you'd want. Several of these pieces can't reasonably be protocols. I have trouble imagining three different implementations of Observable, and certainly not of Subscription. (If you can't imagine three implementations, it's probably not a protocol.) Trying to make Observable into a protocol definitely causes the whole thing to explode.
Subscription is just a wrapper around a function, so that's struct. Observable is naturally a class. The rest is possibly fine; your problems there are mostly syntax.
import Foundation
typealias Observer<T> = (T) -> ()
struct Subscription
let cancel: () -> Void
final class Observable<T>
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: [weak self] in self?.observations[uuid] = nil )
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
struct First: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Second: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
struct IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(lightDependency: abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(lightDependency: abc)
struct Mock: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
class Test
func test()
let abcMock = Mock()
let client = Client(lightDependency: abcMock)
The Observer implementation here is based on my Subject implementation. Note that this is part of a system that has several quirks that I don't love (Dave Delong's Syzygy is better).
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
add a comment |
You've overused protocols here, but this is the syntax you'd want. Several of these pieces can't reasonably be protocols. I have trouble imagining three different implementations of Observable, and certainly not of Subscription. (If you can't imagine three implementations, it's probably not a protocol.) Trying to make Observable into a protocol definitely causes the whole thing to explode.
Subscription is just a wrapper around a function, so that's struct. Observable is naturally a class. The rest is possibly fine; your problems there are mostly syntax.
import Foundation
typealias Observer<T> = (T) -> ()
struct Subscription
let cancel: () -> Void
final class Observable<T>
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: [weak self] in self?.observations[uuid] = nil )
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
struct First: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Second: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
struct IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(lightDependency: abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(lightDependency: abc)
struct Mock: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
class Test
func test()
let abcMock = Mock()
let client = Client(lightDependency: abcMock)
The Observer implementation here is based on my Subject implementation. Note that this is part of a system that has several quirks that I don't love (Dave Delong's Syzygy is better).
You've overused protocols here, but this is the syntax you'd want. Several of these pieces can't reasonably be protocols. I have trouble imagining three different implementations of Observable, and certainly not of Subscription. (If you can't imagine three implementations, it's probably not a protocol.) Trying to make Observable into a protocol definitely causes the whole thing to explode.
Subscription is just a wrapper around a function, so that's struct. Observable is naturally a class. The rest is possibly fine; your problems there are mostly syntax.
import Foundation
typealias Observer<T> = (T) -> ()
struct Subscription
let cancel: () -> Void
final class Observable<T>
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: [weak self] in self?.observations[uuid] = nil )
protocol A
protocol B
protocol C
protocol AbcObservable
var aAdded : Observable<A> get
var bAdded : Observable<B> get
var cAdded : Observable<C> get
struct First: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Second: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
struct Client
let lightDependency: AbcObservable
init(lightDependency: AbcObservable)
self.lightDependency = lightDependency
struct IoCContainer1
let client: Client
init()
let abc: AbcObservable = First()
client = Client(lightDependency: abc)
class IoCContainer2
let client: Client
init()
let abc: AbcObservable = Second()
client = Client(lightDependency: abc)
struct Mock: AbcObservable
let aAdded = Observable<A>()
let bAdded = Observable<B>()
let cAdded = Observable<C>()
class Test
func test()
let abcMock = Mock()
let client = Client(lightDependency: abcMock)
The Observer implementation here is based on my Subject implementation. Note that this is part of a system that has several quirks that I don't love (Dave Delong's Syzygy is better).
edited Mar 28 at 2:11
answered Mar 28 at 2:06
Rob NapierRob Napier
213k29 gold badges317 silver badges446 bronze badges
213k29 gold badges317 silver badges446 bronze badges
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
add a comment |
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
I understand your answer as "use Observable as concrete type". But my question was how to keep it abstract. I agree with you that Observable will not have many implementations and it is stupid to do it as abstract. I wanted to write the essence of my problem and I used Observable in the example to simplify. In a real situation, I had DataManager instead of Observable, that has many implementations. I added remark in my question to avoid this confusion. Sorry for bad example.
– Valentine Zakharenko
Mar 28 at 2:43
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
There is no equivalent for C# or Java generic interface in Swift. Protocols are a different thing with different patterns. Can you give an example of the actual DataManager you're trying to implement? Typically the solution is to slice the problem along a different axis than you might in C#.
– Rob Napier
Mar 28 at 4:41
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
As an example, take a look specifically at stackoverflow.com/questions/55104199/…. While it is possible to shoe-horn a protocol into that client (ClientType), it is much more powerful and flexible (and easier!) to extract the non-generic piece that actually changes (ClientEngine). I have a similar patterns for key-value stores like UserDefaults if that's the kind of thing you're building.
– Rob Napier
Mar 28 at 4:46
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
It's not quite right of me to say there's no equivalent to generic interfaces in Swift. They don't exist today. They will probably exist some day, and we call them Generalized Existentials. I didn't mean to imply that the concept was antithetical to Swift's "protocol oriented programming." GE's will be a very important addition, and we all know it. That said, many cases that cause people to reach for them have better and simpler solutions in Swift, even if they did exist, like the client/transport example above. github.com/apple/swift/blob/master/docs/GenericsManifesto.md
– Rob Napier
Mar 28 at 13:11
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388214%2fwhat-is-equivalent-for-c-sharp-or-java-generic-interface-in-swift%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Might be useful to watch developer.apple.com/videos/play/wwdc2018/406
– matt
Mar 28 at 0:03
1
All the answers I want to type here look like "stop stop stop stop stop stop." Do not start with abstract inversion of control. Start with a goal in mind for your software, and from there, extract generic solutions. There are way, way too many protocols here, and they look like they're just trying to stand-in for abstract classes maybe? Protocols are not abstract classes. They're not about inheritance. They're about extension. What actual thing do you want this for? From that, we can design often very elegant solutions (not every time, but often).
– Rob Napier
Mar 28 at 1:27
If you're interested in building observables, take a look at github.com/davedelong/Syzygy/tree/master/SyzygyCore/Properties for one fairly powerful approach (while being much smaller than RxSwift, which is a much more powerful approach). Or you can start with an even simpler model that I use, and is probably much easier to understand: gist.github.com/rnapier/981e86fbf345b049c1df41f63e4a2c6e
– Rob Napier
Mar 28 at 1:31
1
"I caught that protocol in swift is analog of the interface in C# or Java." This is probably the heart of your mistake. This isn't a really great analogy. They're not unrelated, but the use of protocols is very different, particularly protocols w/ associated types (what you're thinking of as "generic protocols"). They're definitely not the tool to start with in Swift. They will generally arise out of code where you find duplication, rather than being something you start with.
– Rob Napier
Mar 28 at 1:34
If you're looking for IoC patterns in Swift, see stackoverflow.com/a/55368056/97337 for an example (at the bottom of the answer, not the type-eraser part at the top)
– Rob Napier
Mar 28 at 1:53