I am a newbie in Go lang , I was trying to understand Go Interface by writing a simple piece of code . I am getting an error , as I am not able to understand the correct way of referring to a Interface method kindly tell me where I am going wrong.
type Info interface {
Noofchar() int
}
type Testinfo struct {
noofchar int
}
func (x Testinfo)Noofchar() int {
return x.noofchar
}
func main(){
var t Info
fmt.Println(x.Testinfo)
fmt.Println("No of char ",t.Noofchar())
x.noofchar++
fmt.Println("No of char ",t.Noofchar())
}
Am I referring to the method correctly by t.Noofchar() ? or there is something else that I am missing
Methods typically receive pointers to a struct.
func (x Testinfo)Noofchar() int {
changed to
func (x *Testinfo)Noofchar() int {
Took out var x Info in the beginning, refactored your main() just a bit and the resulting code in play is:
package main
import "fmt"
type Info interface {
Noofchar() int
Increment()
}
type Testinfo struct {
noofchar int
}
func (x *Testinfo) Noofchar() int {
return x.noofchar
}
func (x *Testinfo) Increment() {
x.noofchar++
}
func main(){
var t Info = &Testinfo{noofchar:1}
fmt.Println("No of char ",t.Noofchar())
t.Increment()
fmt.Println("No of char ",t.Noofchar())
}
http://play.golang.org/p/6D-LzzYYMU
In your example you modify x directly. If you're passing an interface around, you don't have access to the underlying data structures, only the methods. So I changed your direct increment to an Increment() method.
x is a variable to which you can assign anything that implements the Info interface. You've assigned nothing to that variable.
Once you assign something, x.noofchar++ will not work because again x can hold anything that implements the Info interface, which means you can only access the methods defined by that interface. Interfaces do not allow direct access to fields.
The only method defined in the Info interface is the Noofchar() int method, so that is the only way to interact with the value stored in x.
The x defined by the method receiver (x Testinfo) isn't at all related to the var x Info variable. That x does have direct access to the struct fields.
The t.Noofchar() calls are correct and will work.
Related
If the postfix operator of a custom function is declared at file scope - as in my previous post - there must be a way to access such a function from another Swift 3 file in the same Xcode project.
Apple’s documentation on custom functions states that “New operators are declared at a global level …“ so I can presume the creators of Swift 3 would consider it important for a custom function to be accessed globally. But for a novice in Swift it is not self-evident how I would do this.
Based on code in my previous accepted answer (here) what would I need to do so a custom function can be accessed from another file elsewhere in the project ?
FINAL EDIT
The solution is embarrassingly simple (see accepted answer) and hopefully other Swift novices may also find it useful.
A postfix operator % is declared globally while an Extension of Int reads an Int variable from another file. Extensions of Double and CGFloat as well as Int are also possible.
CustomOperators.swift
import UIKit
postfix operator %
extension Double {
static postfix func % (n: Double) -> Double {
return Double(n) / 100
}
}
extension Int {
static postfix func % (n: Int) -> Double {
return Double(n) / 100
}
}
extension CGFloat {
static postfix func % (n: CGFloat) -> Double {
return Double(n) / 100
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
let test1: Double = 93.7
let test2: Int = 80
let test3: CGFloat = 70
override func viewDidLoad() {
super.viewDidLoad()
print(test1%) // prints '0.937'
print(test2%) // prints '0.8'
print(test3%) // prints '0.7'
}
}
Thanks marosoiae, and also Martin R and unniversal for your input.
EDIT 2
Martin R’s comments prompted me to try a further example with my custom postfix function defined in Utils but in file scope rather than as a static postfix function. Utils becomes an empty class for custom functions all defined in file scope outside the class.
import UIKit
class ViewController: UIViewController {
let value: Int = 25
override func viewDidLoad() {
super.viewDidLoad()
example1()
example2()
}
func example1() {
// 1. call to a function in Utils with an explicit value
// and nothing returned from Utils.
// Note this uses literal postfix syntax i.e. 25%
Utils.25%
// Debug message:
// Type 'Utils' has no member '25'
}
func example2() {
// 2. call to a function in Utils with an argument
// declared in UIViewController and nothing returned from Utils
Utils.(Int: value)%
// Debug message
// Expected member name following '.'
}
}
Utils.swift now compiles but from debug messages that Xcode reports with both examples, it is clear that the token '%' is expected immediately following the '.'.
Even without returning a variable from Utils.swift, this is obviously not how to call a postfix function in Utils.swift from a file elsewhere in the project. My question remains: how would I do it ?
EDIT 1
At this point it might help to include some code so I created a class with static functions, following the syntax (as far as possible) used in Unniversal's answer. I decided to try static functions if these help avoid cluttering the global scope with methods that should be owned by a class/struct.
File 1 - Utils
import UIKit
postfix operator %
class Utils {
static func yourFunction(){
//Do your stuff here
}
static func yourFunction1(value: Int) {
print(value)
}
static postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
}
The static function % reports
Member operator '%' must have at least one argument of type 'Utils'
which I’d expect to disappear once an argument is supplied from another file.
The following code shows four ways I tried to supply an argument to static functions in Utils. I ran the project with one example at a time
File 2 - UIViewController
import UIKit
class ViewController: UIViewController {
let value: Int = 25
var percentage = Double()
override func viewDidLoad() {
super.viewDidLoad()
// example1()
// example2()
// example3()
// example4()
}
func example1() {
// 1. call to a function in Utils with no argument and no return (i.e. suggested answer)
Utils.yourfunction()
// Debug messages:
// Type 'Utils' has no member 'yourfunction'
// Did you mean 'yourFunction'?
// Did you mean 'yourFunction1'?
}
func example2() {
// 2. call to a function in Utils with argument and no return
Utils.yourfunction1(Int: Int)
// Debug messages:
// Type 'Utils' has no member 'yourfunction'
// Did you mean 'yourFunction'?
// Did you mean 'yourFunction1'?
}
func example3() {
// 3. call to a function in Utils with argument and returning a value for percentage
Utils.%() {
return Int(percentage)
}
// Debug message:
// Use of unresolved operator '.%'
}
func example4() {
// 4. call to a function in Utils with argument and returning a value for percentage
percentage = Utils.%(Int: value) -> Int {
return Int(percentage)
}
// Debug messages:
// Use of unresolved operator '.%'
// Expected type before '->'
// Expected type after '->'
}
}
As far as I can see, static functions Utils.yourFunction and Utils.yourFunction1 can’t be accessed from outside Utils, as shown in example 1 and 2. And the postfix operator % seems to cause Xcode to report Use of unresolved operator ‘.%’, as shown in example 3 and 4. However these problems might be the way I adapted the syntax used by Unniversal.
Any function declared at file scope will have the implicit scope internal and will be visible in the rest of the project/module.
I recommend reading the access control guide for more information.
Edit:
I'm still not sure what you're trying to do, but it looks like you are mixing global functions with static methods and custom operators.
If what you want is to declare a custom operator that you can use in any other file in the project, the solution is in the documentation that you linked in your question.
So this is what you need to declare a custom % (as you defined it) for the Int type:
CustomOperators.swift
postfix operator %
extension Int {
static postfix func % (n: Int) -> Double {
return Double(n) / 100
}
}
main.swift
print(90%) //outputs "0.9"
That's all there is to it. You simply declare the operator globally: postfix operator % and you define the operator function as a static method in a extension on the Int type.
Now you can use your new operator in other files (like I did in main.swift).
If you want a function to be accessed globally I would recommend to create a class that has static functions. For example
class Utils {
static func yourFunction(){
//Do your stuff here
}
}
To use it :
Utils.yourfunction()
I'm not talking about pointers to C functions, but to a method within a Swift type.
struct Test: GeneratorType {
var methodPointer: mutating () -> Bool? // Non-working guess
var which: Bool
init() {
which = false
methodPointer = which ? &testMethod1 : &testMethod2 // Also non-working guess
}
//...
}
The compiler says "mutating" isn't legal as part of a function declaration. (Actually, it just suggests a semi-colon there.) And for the pointer initialization (after I remove mutating), the compiler thinks I'm trying to call the functions and use their results instead. I want to use the methods as objects in-and-of themselves here, not as a function call. Later on I want to use the pointed-to method within next; without figuring this out, I'll have to resort to an enumeration flag and manually choosing which method to call within next.
I hope there's some part of closure mechanics that allows this. Maybe something like this page, which describes functions returning functions. But none of the examples I've seen mention mutating methods.
See if this helps you.
class Something {
var f: ( () -> Int )?
let f1 = { () -> Int in /* do some action here */ return 1}
let f2 = { () -> Int in /* do some action here */ return 2}
func ff(which: Bool) {
f = which ? f1 : f2
}
func act() {
if let f = f {
f()
}
}
}
Here is how I do it -
class FcnArgs { //#goal pass a fcn as arg
class func demo() {
let fPtr = funcToPointTo; //#type '((Int)->String)'
print(fPtr(4));
}
class func funcToPointTo(_ i : Int) -> String {
print("I Was passed \(i)");
return "I was returned";
}
}
FcnArgs.demo() output:
I Was passed 4
I was returned
Is there an example of how dispatch_once should be used in Swift? (Preferably one from Apple.)
Note: In this case, I'm not using it for a singleton; I want to run arbitrary code exactly once.
Update: I'm mainly interested in the convention recommended when using this in an instance method, but usage in a class method, function, and in the global context would be useful for completeness sake.
dispatch_once_t is type alias (Int). Header documentation:
/*!
* #typedef dispatch_once_t
*
* #abstract
* A predicate for use with dispatch_once(). It must be initialized to zero.
* Note: static and global variables default to zero.
*/
typealias dispatch_once_t = Int
And here's the quote from dispatch_once documentation:
The predicate must point to a variable stored in global or static
scope. The result of using a predicate with automatic or dynamic
storage (including Objective-C instance variables) is undefined.
Token variable must be stored in global / static scope and must be initialized to zero, which leads to this code:
import Foundation
var token: dispatch_once_t = 0
dispatch_once(&token) { () -> Void in
print("Called once")
}
It doesn't work if you omit = 0 (token initialization), because compiler yields error Address of variable 'token' taken before it is initialized despite the fact that statics and globals default to zero. Tested in Xcode 7B2.
More examples based on comment. If you're inside class method you have several possibilities.
You can't declare static property inside method otherwise compiler yields Static properties may only be declared on a type error. This doesn't work:
class func doItOnce() {
static var token: dispatch_once_t = 0
...
}
Must be declared on a type. This was introduced in Swift 1.2 (Xcode 6.3 IIRC).
“static” methods and properties are now allowed in classes (as an
alias for “class final”). You are now allowed to declare static stored
properties in classes, which have global storage and are lazily
initialized on first access (like global variables). Protocols now
declare type requirements as “static” requirements instead of
declaring them as “class” requirements. (17198298)
So, what we can do if we don't like globals?
Static variable on a type
class MyClass {
private static var token: dispatch_once_t = 0
class func doItOnce() {
dispatch_once(&token) {
print("Do it once")
}
}
}
Static in a method wrapped in struct
Don't like static property on yur class? Would like to have it in your method? Wrap it in struct like this:
class func doItOnce() {
struct Tokens { static var token: dispatch_once_t = 0 }
dispatch_once(&Tokens.token) {
print("Do it once")
}
}
Actually I'm not aware of any Apple recommendation, best practice, ... how to do it for dispatch_once. Simply use whatever you like most, feels good to you and just meet criteria global / static scope.
For those of you who are curious, for me this approach has been useful for this purpose:
class SomeVC : UIViewController {
private var token: dispatch_once_t = 0
public override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
dispatch_once(&token) { () -> Void in
self.doSomethingOnce()
}
}
}
By not declaring a static var it has the expected behaviour. That being said, this is definitely NOT RECOMMENDED for any serious project, since in the Docs (as your well said) it states:
The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.
If we don't want to run into any future weird bugs and undefined behaviour I would just stick to what Apple says. But it's still nice to play around with these things, isn't it? =)
the robertvojta's answer is probably the best. because i try always to avoid import Foundation and use 'pure' Swift solution (with Swift3.0 i could change my opinion), I would like to share with you my own, very simple approach. i hope, this code is self-explanatory
class C {
private var i: Int?
func foo()->Void {
defer {
i = 0
}
guard i == nil else { return }
print("runs once")
}
}
let c = C()
c.foo() // prints "runs once"
c.foo()
c.foo()
let c1 = C()
c1.foo() // prints "runs once"
c1.foo()
class D {
static private var i: Int?
func foo()->Void {
defer {
D.i = 0
}
guard D.i == nil else { return }
print("runs once")
}
}
let d = D()
d.foo() // prints "runs once"
d.foo()
let d2 = D()
d.foo()
Calling a method from its name (in a String format) can be sometimes useful.
In Swift it is recomended to change behavior and to use closures to do something "dynamically", so for example you can have a dictionary of functions, with the name as the key, and the implementation as the value.
However, sometimes you want to simply know "how to do it", and this is the reason of this question.
So, how to call dynamically a Swift method starting from it's name as string?
In Objective C it was simple:
[self performSelector:NSSelectorFromString(#"aSelector")];
But performSelector is banned in Swift
Is there any alternative?
In Swift, you should use closures and change your approach.
However, if you want to use performSelector to dynamically call a method given only it's String signature, altough it's not supported natively, I've found how to do it.
It is possible to create a C alternative to performSelector that:
works even on native swift classes (non objective-c)
takes a selector from string
However it's not so straightforward to implement a complete version of it, and it's necessary to create the method in C.
in C we have dlsym(), a function that returns a pointer to a function given the char symbol.
Well, reading this interesting post:
http://www.eswick.com/2014/06/inside-swift/
I've learned a lot of interesting things about swift.
Swift instance methods are plain functions with a specific signature, like this
_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString
where the "self" value is passed as the last parameter
in short you can call it directly from the c side without any kind of bridging, it is sufficient to rebuild the correct function signature.
In the signature above, there is the name of the project (FirstSwiftTest) and the lenght (14), the name of the class (ASampleClass) and the lenght (12), the name of the function (aTestFunction) and the lenght (13), then other values as the return type ecc ecc. For other details look at the previous link
The function above, is the representation of this:
class ASampleClass
{
func aTestFunction() -> NSString
{
println("called correctly")
return NSString(string: "test")
}
}
Well, on the c side, I was able to create this function
#include <stdio.h>
#include <dlfcn.h>
typedef struct objc_object *id;
id _performMethod(id stringMethod, id onObject)
{
// ...
// here the code (to be created) to translate stringMethod in _TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString
// ...
id (*functionImplementation)(id);
*(void **) (&functionImplementation) = dlsym(RTLD_DEFAULT, "_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString");
char *error;
if ((error = dlerror()) != NULL) {
printf("Method not found \n");
} else {
return functionImplementation(onObject); // <--- call the function
}
return NULL
}
And then called it on the swift side
let sampleClassInstance = ASampleClass()
println(_performMethod("aTestFunction", sampleClassInstance))
The function resulted in these statement printed on the log:
called correctly
test
So it should be not so difficult to create a _performMethod() alternative in C that:
creates automatically the function signature (since it seems to have a logic :-)
manages different return value types and parameters
EDIT
In Swift 2 (and maybe in Beta3, I didn't try) It seems that performSelector() is permitted (and you can call it only on NSObject subclasses). Examining the binary, It seems that now Swift creates static functions that can be specifically called by performSelector.
I created this class
class TestClass: NSObject {
func test() -> Void {
print("Hello");
}
}
let test = TestClass()
let aSel : Selector = NSSelectorFromString("test")
test.performSelector(aSel)
and now in the binary I find
000000010026d830 t __TToFC7Perform9TestClass4testfT_T_
At this time, I don't understand well the reasons behind this, but I'll investigate further
You could call a method from a String this way:
let foo = <some NSObject subclass instance>
let selectorName = "name"
foo.perform(Selector(selectorName))
It is available only when your foo class is subclass of NSObject
swift3 version
class MyClass:NSObject
{
required public override init() { print("Hi!") }
public func test(){
print("This is Test")
}
public class func static_test(){
print("This is Static Test")
}
}
if let c: NSObject.Type = NSClassFromString("TestPerformSelector.MyClass") as? NSObject.Type{
let c_tmp = c.init()
c_tmp.perform(Selector("test"))
c.perform(Selector("static_test"))
}
Using golang html/template (same behavior with text/template). If I have a struct with a member that is of an interface type, I cannot access members of the underlying type (specifically trying to access fields that are on a struct that implements interface InnerInterface but is return via the InnerInterface interface type, not the struct type).
http://play.golang.org/p/ZH8wSK83oM
package main
import "fmt"
import "os"
import "html/template"
type InnerInterface interface{ InnerSomeMethod() }
type MyInnerStruct struct { Title string }
func (mis MyInnerStruct)InnerSomeMethod() { fmt.Println("Just to show we're satisfying the interface") }
type MyOuterStruct struct { Inner InnerInterface }
func main() {
fmt.Println("Starting")
arg := MyOuterStruct{Inner:MyInnerStruct{Title:"test1"}}
err := template.Must(template.New("testtmpl").Parse("{{.Inner.Title}}")).Execute(os.Stdout, arg)
if err != nil { panic(err) }
}
Changing: type MyOuterStruct struct { Inner InnerInterface } to a totally generic interface, i.e. type MyOuterStruct struct { Inner interface{} } makes it render properly. This leads me to believe that interface{} is treated specially by the rendering engine.
Is there a better way to do this than to use interface{} whenever I want to be able to dynamically evaluate fields like this?
You're correct with saying that interface{} is handled differently by the rendering
engine. Only interface{} values are unpacked, interface values that have a method set are not.
I suppose the reasoning behind this is that if you have a interface type, you specifically limit the type to the method set. Therefore, you don't want the template engine trying to access members that may lie behind that interface.
The 'problem' is caused by the function indirect in exec.go:
func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
if v.IsNil() {
return v, true
}
if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
break
}
}
return v, false
}
This method is called to get to the deepest value of a reflected value.
Suppose you have a pointer on a pointer on a pointer, this function will get return the
last of these. The same goes for interface values. The crux is that as soon as a
interface value has more than 0 methods, the indirection stops there. Exactly the
behaviour you're describing.
As this seems to be intended behaviour, what you can do is to define a Title() string
method in your interface and let it return the string.