I'm trying to write some helper functions and am getting an 'Invalid Redeclaration' error of some similar methods. If anyone can explain why these methods collide I would be very thankful.
func CGRectModify(rect: CGRect, x: CGFloat) -> CGRect {
return CGRectMake(x, rect.origin.y, rect.size.width, rect.size.height)
}
func CGRectModify(rect: CGRect, y: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, y, rect.size.width, rect.size.height)
}
func CGRectModify(rect: CGRect, width: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, rect.origin.y, width, rect.size.height)
}
func CGRectModify(rect: CGRect, height: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height)
}
I would think that because the second parameter has a different external name, the method would be understood to have a different signature. It seems that is not the case.
I've been using Apple's doc for reference, but in the section of Local and External Parameter Names for Methods I could not find my answer. Any input is much appreciated.
The rule of "automatic external parameter names" for functions are different from methods.
Swift applies different rules depends on the type of callables.
Functions/Closures → document
No "automatic external parameter names" are performed.
func f(x:Int, y:Int) { /* ... */ }
let c = { (x:Int, y:Int) -> Void in /* ... */ }
f(1, 2)
c(1, 2)
Initializers → document
"automatic external parameter names" are the default for every parameters.
class Foo {
init(x:Int, y:Int) { /* ... */ }
}
let foo = Foo(x: 1, y: 2)
Methods → document
"automatic external parameter names" except for the first parameter.
extension Foo {
func bar(x:Int, y:Int) { /* ... */ }
}
foo.bar(1, y:2)
Subscript → document missing?
No "automatic external parameter names" are performed.
extension Foo {
subscript(x:Int, y:Int) -> Void {
get { /* ... */ }
}
}
foo[1, 2]
And a special rule for ...
Default Values
func fz(x:Int, y:Int, z:Int = 1) { /* ... */ }
fz(1, 1, z: 1)
Of course you can override these default behaviors using:
_ name:Type: disable "automatic external parameter names"
#name:Type: force "automatic external parameter names"
externalName internalName:Type: explicit external name
This actually looks like a bug in the documentation. In the section I originally linked to, Local and External Parameter Names for Methods the follow explanation is written.
This default behavior effectively treats the method as if you had written a hash symbol (#) before the numberOfTimes parameter:
func incrementBy(amount: Int, #numberOfTimes: Int) {
count += amount * numberOfTimes
}
This is not the case. When I do add the hash symbol (#) to my second parameter, the compiler error does not occur.
func CGRectModify(rect: CGRect, #height: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height)
}
Related
this example grabbed from geeksforgeeks.
// C++ program to demonstrate function
// declaration outside class
#include <bits/stdc++.h>
using namespace std;
class Geeks
{
public:
string geekname;
int id;
// printname is not defined inside class definition
void printname();
// printid is defined inside class definition
void printid()
{
cout << "Geek id is: " << id;
}
};
// Definition of printname using scope resolution operator ::
void Geeks::printname()
{
cout << "Geekname is: " << geekname;
}
int main() {
Geeks obj1;
obj1.geekname = "xyz";
obj1.id=15;
// call printname()
obj1.printname();
cout << endl;
// call printid()
obj1.printid();
return 0;
}
I mean, function like printname in this example.
And in rust..., this example grabbed from exercism and I modified little bit.
// This stub file contains items which aren't used yet; feel free to remove this module attribute
// to enable stricter warnings.
#![allow(unused)]
pub struct User {
name: String,
age: u32,
weight: f32,
}
impl User {
pub fn new(name: String, age: u32, weight: f32) -> Self;
pub fn name(&self) -> &str;
...
...
}
pub fn User::name(&self) -> &str {
unimplemented!()
}
...
...
like this or somewhat difference, but declare first definition later.
Sorry for my bad english, and therefore I included many lines of code and I needed to add some more detail because SO wants that.
There's no way to do this in Rust?
You can do the same thing in Rust. You can implement particular struct methods, from anywhere inside the crate.
This is mostly pointless in Rust, but I'm going to provide an example where this might prove useful.
Soundness concerns leak to the surrounding module, and thus you can reduce the scope of this issue by doing this:
mod a {
pub struct A;
impl A {
pub fn a(&self) {
// here we can't access any unsafe functions specific to A
// unsafe { some_unsafe_helper() }; // compiler error
println!("Called ::crate::a::A::a implemented in ::crate::a");
}
}
mod less_safe {
unsafe fn some_unsafe_helper() {}
impl super::A {
pub fn b(&self) {
// here we have to uphold invariants, in this case, by doing nothing
unsafe { some_unsafe_helper() };
println!("Called ::crate::a::A::b implemented in ::crate::a::less_safe");
}
}
}
}
fn main() {
let example = a::A;
example.a();
example.b();
}
This prints:
Called ::crate::a::A::a implemented in ::crate::a
Called ::crate::a::A::b implemented in ::crate::a::less_safe
Playground
For example I have following sample code
fun f<T>( cb: (T, Int) -> Unit ): Unit {
println("f called with cb which accepts 2 arguments");
}
fun f<T>( cb: (T) -> Unit ): Unit {
println("f called with cb which accepts 1 argument");
f<T> {item, position -> cb(item) }
}
fun main(args : Array<String>) {
f { item -> }
f { item, position -> }
}
Obliviously I want f function choose right implementation depends on amount of arguments I'm going to pass to closure
Currently kompiller gives me error:
(8, 7) : Overload resolution ambiguity:
internal fun <T> f(cb: (T, kotlin.Int) -> kotlin.Unit): kotlin.Unit defined in root package
internal fun <T> f(cb: (T) -> kotlin.Unit): kotlin.Unit defined in root package
Code in online sandbox: http://kotlin-demo.jetbrains.com/?publicLink=100745728838428857114-628607155
Compiller version: org.jetbrains.kotlin:kotlin-gradle-plugin:0.10.770
UPD: related issue on youtrack: https://youtrack.jetbrains.com/issue/KT-6939
Thanks to #miensol I realized it was my mistake. I forgot to specify type for T while calling f().
Fixed code:
fun f<T>( cb: (T, Int) -> Unit ): Unit {
println("f called with cb which accepts 2 arguments");
}
fun f<T>( cb: (T) -> Unit ): Unit {
println("f called with cb which accepts 1 argument");
f<T> {item, position -> cb(item) }
}
fun main(args : Array<String>) {
f<String> { item -> }
f<Boolean> { item, position -> }
}
I thought closures and functions are same thing. But when referencing to a property inside local function compiler doesn't require self. But inside closure it requires to write self. What i mean is why this two things are different?
The sample code for clarity:
class Foo {
let bar = "bar"
func baz() {
func localBaz() {
println(bar) // No complain from compiler.
}
let bazClosure = {
println(self.bar) // Here if I write just println(bar), compiler complains.
}
}
}
You expectation is wrong - functions and closures in Swift are not the same thing. A func essentially sets up a lazy var binding with a [unowned self] declaration. Thus, if you want to get rid of func you could transform the following:
class Foo {
let bar = "bar"
// this is not your 'baz'; just an example
func baz () { println (bar) }
}
}
as
class Foo {
let bar = "bar"
lazy var baz = { [unowned self] in println (self.bar) }
}
You can see that func is doing more than just a closure.
Furthermore, and importantly, func sets up a recursive binding environment which allows the body of func bar to reference bar. Thus you can write:
1> class Foo {
2. func fact (x:Int) -> Int {
3. if 1 == x { return x }
4. else { return x * fact (x - 1) }}
5. }
6> Foo().fact(5)
$R0: (Int) = 120
but not
7> class Foo {
8. lazy var fact = { (x:Int) -> Int in
9. if 1 == x { return x }
10. else { return x * fact (x - 1) }}}
repl.swift:10:27: error: variable used within its own initial value
else { return x * fact (x - 1) }}}
^
Indeed, I do not know why closure need self in swift to access instance properties but let's think about it.
Your baz() is a class function, I mean it belongs to the class Foo and the closure like a external function. In Objective-C all class function actually need a self argument to invoke that function.
Therefore a closure need a self pointer (or something named self reference the instance of Foo) to access its property.
Is there any difference in swift between function declaration:
func function(a: String) {
print(a);
}
function("test");
and closure assignment:
let closure = {
(a: String) in
print(a);
}
closure("test");
Is there any difference between those?
Named or anonymous
func function(a: String) {
print("\(a), name: \(__FUNCTION__)");
}
let closure = { (a: String) in
print("\(a), name: \(__FUNCTION__)");
}
Capture List
supported in closures only:
let obj = FooClass()
let closure = { [weak obj] in ... }
Curried function
supported in functions only:
func curriedFunc(x:Int)(y:Int) { ... }
let curried = curriedFunc(1)
curried(y:2)
Similar, but not exact the same with using closure:
let closure = { (x:Int) in { (y:Int) in ... }}
Generics
supported in functions only:
func function<T>(x:T) { ... }
Referenceability from its own initial declaration
supported in global functions only:
func recursive(var x:Int) -> Int {
...
return condition ? x : recursive(x)
}
You can do this using closure also:
var recursive:((Int) -> Int)!
recursive = { (var x) in
...
return condition ? x : recursive(x)
}
But this is not recommended because this causes strong reference cycles.
Overload
supported in functions only:
func function(a: String) { print("String: \(a)") }
func function(a: Float) { print("Float: \(a)") }
n.b. You can reference them as a closure like this:
let f:(Float) -> Void = function
Another difference: recursivity inside another function
Nested functions cannot be recursive:
func foo() {
func bar() { bar() } // does not compile
}
but closures inside other functions can be recursive:
func foo() {
var bar: (() -> ())!
bar = { bar() }
}
I'm trying to create 2 protocols ArithmeticType and MathematicType that will be used in where clauses of generic operator functions
protocol ArithmeticType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
}
extension Int : ArithmeticType {
}
extension Double : ArithmeticType {
}
extension Float : ArithmeticType {
}
ArithmeticType works as expected and either Int, Float and Double conform to it. However the following fails
import Darwin
protocol MathematicType {
func sin(x: Self) -> Self
}
extension Double : MathematicType {
}
extension Float : MathematicType {
}
on console output of the playground I read:
Playground execution failed: <EXPR>:35:1: error: type 'Double' does not conform to protocol 'MathematicType'
extension Double : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Double -> Self'
func sin(x: Self) -> Self
^
<EXPR>:39:1: error: type 'Float' does not conform to protocol 'MathematicType'
extension Float : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Float -> Self'
func sin(x: Self) -> Self
^
I would like that math functions behave like the operators above. Is there any way?
== EDIT:
Now I realize that trying to simplify my question was a bad idea. the context is this class (vector of optional values)
class Vector<T> {
var data=[T?]()
init(fromArray: Array<T>) {
for i in fromArray {
data.append(i)
}
}
init() {
}
init(count: Int){
for i in 0..<count {
data.append(nil)
}
}
init(count: Int, repeatedValue: T) {
for i in 0..<count {
data.append(repeatedValue)
}
}
func count() -> Int {
return data.count
}
func append(newElement: T?) {
data.append(newElement)
}
subscript(index: Int) -> T? {
let i = index>0 ? index % count() : -index % count()
return data[i]
}
}
outside of it I defined a generic function for the + operator
func +<T where T: ArithmeticType>(left: Vector<T>, right: Vector<T>) -> Vector<T> {
let resultCount = max(left.count(),right.count())
var result = Vector<T>()
for i in 0..<resultCount {
if left[i] != nil && right[i] != nil {
result.append(left[i]!+right[i]!)
}
else {
result.append(nil)
}
}
return result
}
that works as expected, however when I tried to define a generic sin function as
func sin<T where T : FloatingPointType>(x: Vector<T>) -> Vector<T>{
var result = Vector<T>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(sin(o))
}
else {
result.append(nil)
}
}
return result
}
I got "could not find an overload of sin that accepts the supplied arguments"
then my attempt with MathemticType trying to mimic what I already done for + operator
(ArithmeticType was inspired from IntegerAritmeticType source found by command clicking on import swift more than my knowledge of what I was doing)
== UPDATE
If I write a specialized function only for Double
func sin(x: Vector<Double>) -> Vector<Double>{
var result = Vector<Double>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(Darwin.sin(o))
}
else {
result.append(nil)
}
}
return result
}
it works as expected.
So the question may become "How can I generalize this to either Double and Float" ?
The compiler error is because you declared sin() as a method of the MathematicType protocol, and then declared that Double implements MathematicType, but didn't actually write the sin() method.
extension Double {
func sin(x: Double) -> Double {
return Darwin.sin(x)
}
}
I don't think that's what you want, though, is it? You want to be able to write this:
let myAngle = 3.14159
let sineValue = myAngle.sin()
If that's the case, your protocol and extension would need to look like this:
protocol MathematicType {
func sin() -> Self
}
extension Double : MathematicType {
func sin() -> Double {
return Darwin.sin(self)
}
}
Your MathematicType protocol, and your declarations of conformance to it in Float and Double extensions, say that Float and Double should provide sin as an instance method. That is, you're saying one should be able to write code like:
let zero = 0.0 // inferred type Double
zero.sin(1.5707963268) // returns about 1.0
Notice that invocation of sin isn't actually related to the value of zero, so this probably isn't the behavior you want.
You're probably looking to have sin be a free function, so you can just write:
sin(1.5707963268)
Right?
In that case, your work is already done... the standard library defines both:
func sin(x: Double) -> Double
func sin(x: Float) -> Float
If what you actually want is for your MathematicType to be usable as a generic parameter, meaning "a type you can take the sine of", you'll need a generic sin function. Something like this (quick kludgy solution, there's probably better):
func sine<T: FloatingPointType>(x: T) -> T {
if let v = x as? Double {
return sin(v) as T
}
if let v = x as? Float {
return sin(v) as T
}
fatalError("unknown FloatingPointType")
}
(Notice also that there's already a protocol that both Float and Double conform to, so I've used that in the example.)
I think the issue is that operator requirements and instance method requirements are different, even though they syntactically look similar. Operators are always defined at the global level, so an operator requirement is a requirement on an operator at the global level. On the other hand, instance method requirements are requirements on instance methods. There is no way to specify a global function requirement.