What's the difference between the following 2 subscripts?
subscript(position: Int) {
get { ... }
}
subscript(position: Int) {
_read { ... }
}
_read is part of the Swift Ownership story that has been in development for a while now. Since read (the likely name once it goes through Swift Evolution) is fairly advanced concept of the language you will probably want to read at least where it is described in the Ownership Manifesto here to get a more full answer than I'll provide here.
It is an alternative to get on subscripts that allows you to yield a value instead of return a value. This is essential for move only types because they cannot be copied (that is their entire purpose) which is what happens when you return a value. By using read it makes it so you could have for example have an Array of move only types and still use the values in it without taking the ownership of them by moving them. The easiest (and not technically correct since it is a coroutine) way to conceptually think about it is that you get a pointer to the object that read yields.
The sibling of read is modify which is currently in the pitch phase of Swift Evolution here so that can also give you some helpful insight into what read is since it is a coroutine as well.
So for now if Xcode gives you a _read to implement simply change it to get since it is a bug since it isn't an official part of the language yet.
Related
I'm learning Swift, using this guide from the official website, in the form of PlayGround.
And I had this error:
I'm so confused... for one thing, this is an introduction guide, for another, I tried all of these and none of them work:
Luckily I finally got this one to work, but I don't know why...
So, I think my question is:
Why there's an error?
What's the original thought behind this part of guide design? I mean, what do they want to show us originally, knowing it's incorrect...
In my working code case, I don't see I can change my code to what's showing in the original guide example of if condition using optional variable. There's no way for this code:
if let nickname {
print("Hey, \(nickname)")
}
to work, right?
Answering your questions:
There's an error because the Xcode version that you are working with has a Swift version <5.7 (Xcode <14) which does not yet support if let shorthand syntax for optional binding when shadowing an existing optional variable (proposed in SE-0345).
For your second image, you are attempting to use optional binding with an non-optional string literal "something", which is, in semantics, pointless, not to mention being syntactically invalid.
The original idea behind this part of the guide is to familiarize you with the idea of dealing with optionals, specifically "optional binding", which is a technique used to work with optional values. You might wanna look into that via the official Swift language guide.
Short story: Think of variables as boxes. In Swift, these boxes can contain a certain type of data (e.g. String, Int, Bool, etc.). All these types that you might be already familiar with are solid data types that guarantee something of that type will be present in the box. But in some cases, you will be exposed to (or need) uncertainties in which you have no idea whether or not a solid piece of data is present within the box. This is when optional values come in--boxes that do not guarantee the presence of values (this box can either have something solid inside or nothing at all, nil).
Usually, we can force unwrap the optional values, but that can cause an error in your program when the box has nothing inside (Swift be like: hey! you promised me that there's gonna be a value inside the box but there's nothing inside, you untruthful creature! what do I do now? *rage halt*). That's why you need an optional binding: you tell Swift to carefully unwrap it and do something with the potential value inside (if it can be safely unwrapped) and do something else when there's nothing inside. The conventional syntax is:
if let aValue = anOptionalValue {
// if there's something inside the box, do something with it
print("haha found ya", aValue)
} else {
// otherwise do something else
print("oh no! empty box...")
}
Swift will now be happy: "at least you warned me that it might be empty inside and told me exactly how to handle it."
You are trying to use the shorthand syntax for optional binding which is only available after Swift 5.7 + Xcode 14. You'll need to get a Xcode 14 beta to use it.
I'm making a game, where i need to define the object in the radius of the explosion in certain radius. Firstly, i was making it through distance between all objects, but i saw that there is GKRTree class in GameplayKit. But after many tries, it doesn't want to work at all. It just returns empty array in any case. I want to know, are GKRTree class broken or what. If yes, are there any other method to do the same stuff as GKRTree in swift or github. Because i dont want to calculate distance, since it can be use a lot of cpu.
Thanks
Edit: I tried what is described in this answer https://stackoverflow.com/a/38655862/11687591, but it dont work. And there are no another solution about this problem. There is some links, where somebody is talking about broken gkrtree and there is no answer. https://www.reddit.com/r/swift/comments/63frk6/does_anyone_have_a_working_example_of_gkrtree/
https://twitter.com/StayOnTheMove/status/1067067053419520000?s=20
And that's all. One things that i've tried that i created 2 circles. One of them is not moving and in one position all the time. Another is moving to my touch position. Second is smaller than the other one. Larger is a little bit transparent so i can see other circle. I also use print() to see all things that happening in the code. And after all of that, even if there is clearly situation where one circle is inside other one, gkrtree.entities method don't work and it returns empty array.
For what it's worth, GamePlayKit.GKRTree is recently failing for me as of Xcode 11.5+. The following line,
import GameKit
class blah {
private var searchTree: GKRTree<RouteSegment>?
public init() {
searchTree = GKRTree.init(maxNumberOfChildren: 3)
}
}
Using a let expression also gets a nil value.
Edit:
The reason it was returning nil is because I didn't have GameplayKit in the linking phase of the project. Duh. By default, all the iOS frameworks are on the search path, which doesn't mean they will be available at runtime. I'm not sure why Apple chose this mechanism. When I traced the assembly code step into the init() function, I found it just returned nil; there must be some stubs in the API.
Solution for me: make sure that GameplayKit is in the linked binaries phase in the project settings.
What does = do here?
List<Segment> totalSegments = flight.departureFlight.segments;
Do both, totalSegments and flight.departureFlight.segments point to the same memory reference or totalSegments has the same data as flight.departureFlight.segments but points to a different memory location?
My understanding was that the latter should happen since dart is pass by value and not reference. However, a very annoying bug occurred when I added this line below that one:
totalSegments.addAll(flight.returnFlight.segments);
This above line actually modified the flight variable which in turn somehow modified the AsyncSnapshot from the StreamBuilder. Although, I wasn't using the variable anywhere else and not modifying other variables mentioned.
This all happened inside build function of a Stateless Widget. Maybe that has to do something with it.
I tried reading dart documentation for it, but either I couldn't find what I am looking for or the information is simply missing there. Read this too, but according to this, my use case shouldn't happen.
When it comes to objects as in your case, you are assigning a reference to an existing object (memory location) to a new variable. While acting upon that reference, you change the same object.
If this is not what you intend, check out answers related to (deep) copying of the objects
You were mistaken by the fact that Dart passes by value, and not by reference. Actually, it is exactly the opposite: (Almost) everything is always passed by reference (Which is usually a good thing!) Therefore, it is quite logical that because you edited totalSegments your departureflight.segments got edited too. It is a synonym. One of the ways to solve your problem would be:
List<Segment> totalSegments = List();
totalSegments.addAll(flight.departureFlight.segments.toList());
List<Segment> totalSegments = flight.departureFlight.segments;
This expression does the following.
Assigns the value of the expression flight.departureFlight.segments to variable totalSegments.
This and only this and nothing more.
There is no need to know what is really happening, because this is what happens.
P.S.
What value will be obtained as a result of executing the expression flight.departureFlight.segments is another question, because it depends on the implementation of the members of the operands of the expression flight.departureFlight.segments.
Here is an example:
assertThat(commentById.getId()).isNotNull();
assertThat(commentById.getContent()).isNotBlank();
assertThat(commentById.getAuthor()).isNotNull();
assertThat(commentById.getAuthor().getUsername()).isNotBlank();
assertThat(commentById.getAuthor().getAvatar()).isNotBlank();
assertThat(commentById.getAuthor().getId()).isNotNull();
Is there anyway to chain this into a single assertThat statement
Sorry for the unclear question. I mean, is there some fluent method calls to chain multiple assertThat statement together. Here is an example I can think of:
assertThat(commentById)
.isNotNull()
.and(Comment::getID).isNotNull()
.and(Comment::getContent).isNotBlank()
.and(Comment::getAuthor).is(author->{
author.isNotNull()
.and(User::getID).isNotNull()
.and(User::getAvatar).isNotBlank()
.and(User::getUsername).isNotBlank()
});
You can utilize satisfies method:
assertThat(commentById.getId()).isNotNull();
assertThat(commentById.getContent()).isNotBlank();
assertThat(commentById.getAuthor()).isNotNull().satisfies(author -> {
assertThat(author.getUsername()).isNotBlank();
assertThat(author.getAvatar()).isNotBlank();
assertThat(author.getId()).isNotNull();
});
This helps to eliminate repeating parts of code while testing nested structures.
If you want the commentById object itself to be tested by "one-liner", it is theoretically possible to apply same approach onto it (assertThat(commentById).satisfies(c -> {assertThat(c.getId()).isNotNull(); ...})), however I state it here only to literally answer your question, actually I don't see any benefit of such expression.
This is not possible at the moment, what is possible is to use extracting but that implies navigating from the current actual to the extracted one without being able to go back to the original actual.
I'm currently starting up work on a project, and my first task is decomposing a God Object that someone else created out of the AppDelegate. I've started by copying code related around managing location out, in the intention of delegating calls to that code into the new object.
I have two statements that are driving me nuts however.
New file:
if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...}
Old file:
if locationManager?.location?.horizontalAccuracy > horizontalAccuracyCheck{...}
You'll notice the code is identical. In both cases self.locationManager? is defined as:
var locationManager: CLLocationManager?
But in the new file, I'm getting a warning about 'value of optional type no unwrapped' -- why? Exact duplicate code, copied & pasted, what would make this different?
Changing the code to unwrap it fixes things:
if (locationManager?.location?.horizontalAccuracy)! > horizontalAccuracyCheck{...}
I can wrap my head around why I need to explicitly unwrap a potentially optional return. But... why only in one place?
The reason is that we're talking here about two quite different languages. One file is Swift 2, the other file is Swift 3.
In Swift 2, you can compare an Optional representing a number with another number using the greater-than or less-than operator. In Swift 3, you can't do that.
Here's a simpler example of the same thing:
let optint : Int? = 7
let ok = optint < 42
That code is legal in Swift 2 but illegal in Swift 3.
As discussed in this Q&A – the Swift migrator will insert a custom fileprivate operator overload in order to allow for optional comparisons to work in Swift 3 the same way they did in Swift 2. Because this overload is fileprivate, you won't be able to use it from any other source files in your project that don't also define it, thus why your comparison fails to compile in the new source file.
Therefore one solution is just to copy it over to your new file. Another is to remove the fileprivate access modifer. The overload will default to internal, and therefore be accessible to other Swift files in your module.
Although really I would just recommend removing the overload entirely and instead write your own explicit logic for optional comparison when it arises – the overload can be too easily misused (as demonstrated by the Swift evolution proposal to remove it).