How do packages work in golang - import

I was trying to understand how packages work in go better in terms of what golang actually enforces rather than what is usually done or considered good practice (we can talk about good practice later too, but I wish to understand go first).
From effective go it says:
"Another convention is that the package name is the base name of its source directory..."
However, the description above doesn't seem to be forced by go or required. Thus, I was wondering, if I was allowed to have multiple files with different package declarations at the top in the same directory base. If I am allowed to have multiple package declaration in the same directory, how do I then import them and use each one separately in the same file? Basically, I guess one of the problem I have is due to the wording of some of the go tutorial/documentation. If it is by convention, then for me, its implied that it is NOT enforced by the language. Because for example, go programmers do NOT write the keyword func for a function by convention. We write func because otherwise go will yell at you and it will not compile. Thus, I wish to clarify this with the example bellow (and if possible change the documentation for go, because this is a big deal in my opinion, how can this be done?).
For example say I have three file A.go, B.go, C.go that print a print function Print() that simply prints a,b,c respectively. They are all on the same base directory called maybe base. Then each has a different package declaration package Apkg, package Bpkg, package Cpkg.
how would you then go and import them? Would something as follow work?
package main
import(
nameA "github.com/user_me/base/Apkg"
nameB "github.com/user_me/base/Bpkg"
nameC "github.com/user_me/base/Cpkg"
)
func main() {
nameA.Print() \\prints a
nameB.Print() \\prints b
nameC.Print() \\prints c
}
or maybe we don't even need to specify the name if the package statments are the top are already different:
package main
import(
"github.com/user_me/base"
)
func main() {
Apkg.Print() \\prints a
Bpkg.Print() \\prints b
Cpkg.Print() \\prints c
}
the printing file are:
A.go:
//file at github.com.user_me/base and name A.go
package Apkg
import "fmt"
func Print(){
fmt.Println("A")
}
B.go:
//file at github.com.user_me/base and name B.go
package Bpkg
import "fmt"
func Print(){
fmt.Println("B")
}
C.go:
//file at github.com.user_me/base and name C.go
package Cpkg
import "fmt"
func Print(){
fmt.Println("C")
}
Also, if you can have a name different from the base, could someone clarify to me how the import is actually done? If the package name is package Apkg in base does the import have to be import github.com/user_me/base or import github.com/user_me/base/Apkg or github.com/user_me/Apkg.
I have not yet tested this but I will do so soon. The importing deal in go has been a little confusing for me and would love to get an answer and share it with the world.

No, it's 1 package per folder, so you would have to have them :
$GOPATH/src/github.com/user_me/base/Apkg/a.go
$GOPATH/src/github.com/user_me/base/Bpkg/b.go
$GOPATH/src/github.com/user_me/base/Cpkg/c.go
You can't even build it otherwise:
┌─ oneofone#Oa [/t/blah]
└──➜ go build
can't load package: package .: found packages pkgA (blah1.go) and pkgB (blah2.go) in /tmp/blah
Your your package name doesn't need to have the same name as the directory they are in, however all files in one directory must have the same package name.
Also, you can rename packages on import, for example:
import (
cr "crypto/rand"
mr "math/rand"
)
Or your library is called main (bad idea btw) :
import m "github.com/user_me/base/main"

Related

how to import a module in Yang

I'm trying to build a CLI. I choose to use 'yang' to do so. I'm new to it and can't find out how to import existing moduls. As exemple I found a module for ospf on github (https://github.com/YangModels/yang/blob/master/vendor/cisco/xe/1631/ietf-ospf.yang) and I would like to import it in my own moduls. Can this be done? how?
EDIT1:
module mininet {
/* name space */
namespace "http://tail-f.com/ns/example/mininet";
prefix mininet;
import ietf-ospf {
prefix ospf;
revision-date 2015-03-09
}
leaf area-id-type {
type yang:area-id-type;
}
}
So I tried to do it this way using Piotr Babij help. Unfortunately this isn't working. What do I need to change?
area-id-type is a typedef of ietf-ospf. The error I have is te following one:
mininet.yang:12:3: error: trailing garbage after module
mininet.yang:12:3: error: unterminated statement
You may import other modules in your own modules by using the import statement. It is described in both RFC 7950 for YANG 1.1 and in RFC 6020 for YANG 1.0. In YANG 1.1 you may import two different revisions of the same module. Other that that, the import statement works the same in both versions.
In practice the basic import looks like this:
module acme-system {
namespace "http://acme.example.com/system";
prefix "acme";
import ietf-yang-types {
prefix "yang";
revision-date 2013-07-15;
}
leaf acme-ip-address {
type yang:dotted-quad;
}
}
If you omit the optional revision-date statement then an undefined module revision is imported. So, in general, it is a good practive to use it.
The mandatory prefix statement lets you to refer to the things in the imported module. In the example the prefix of the imported ietf-yang-types module is yang and, thanks to that, it is clear that yang:dotted-quad refers to a type from that module. In your case you have set the prefix to ospf, so you should have ospf:area-id-type to refer to a type definition from that module. If you import multiple modules you need to ensure their prefixes are unique.
Additionally, you are importing the oldest available revision of the ietf-ospf module. I just hope that this is what you really want to do.
Anyway, once you import a module you are allowed to:
use any grouping and typedef defined at the top level in the imported module or its submodules.
use any extension, feature, and identity defined in the imported module or its submodules.
use any node in the imported module's schema tree in must, path, and when statements, or as the target node in augment and deviation statements.
In the above example the typedef dotted-quad from the ietf-yang-types is used in the acme-system module.

TypeScript import * without creating aliases

In TypeScript, how do you "import *" from a file without creating any aliases?
E.g. I have a file "utils" with top-level exported functions and want to import all them without recreating the aliases for each function.
Something like this:
import * from "utils";
Is that possible?
You can't generate an automatic name, you have to give it a name that is local to your file. This is by design to give each file its own naming context.
// import the default export (something exported with "export default")
import Stuff from "./Stuff";
// import specific things only; aliases in this style are optional
import { ItemA as AliasA, ItemB as AliasB } from "./Stuff";
import { ItemA, ItemB } from "./Stuff";
// import everything at once, grouped under a common name
import * as Stuff from "./Stuff";
I ... want to import all them without recreating the aliases for each function.
It sounds like you'd want the third option from above.
but with this syntax creates an alias
I think the idea is that if you could just import everything while taking the names as they are defined, then you'd have naming collisions. The way this works, you're forced to choose a name for every import, leaving it up to the names you choose to avoid collisions rather than having the imports clobber each other.
I think you can do something similar, but only with .d.ts files. jquery.d.ts does it, but I'm not 100% solid on how it works. You can simply say:
// where the file is really Stuff.d.ts
import "./Stuff";
I think the idea is to create a "Utils" module, attach all the functions and/or classes to it, put export in front of them, then export that instead, such as
module Utils {
export function add(first:number, second:number):number {
return first+second
}
}
export = Utils
Though i haven't played around with the es6 module syntax in typescript yet, as it seems you're implying to use.
You're close it's:
import * as utils from 'utils';
No curly braces.

Protocol Buffers import message depending on another imported message

About import statement, google says that https://developers.google.com/protocol-buffers/docs/proto#services :
You can use definitions from other .proto files by importing them. To import another .proto's definitions, you add an import statement to the top of your file.
By default you can only use definitions from directly imported .proto files.
...Sounds great, but what about that :
1.proto :
message M1{
required string foo = 1;
}
2.proto :
import "1.proto";
message M2{
required M1 m_1 = 1;
}
3.proto :
import "2.proto";
message M3{
required M2 m_2 = 1;
}
So, When parsing 3.proto, M1 shouldn't be accessible because 1.proto is not imported publicly from 2.proto.
However, M2 should be, because it is directely imported from 3.proto...
Thus what about M2.m_1 ? how a compiler should generate classes ?
What the documentation means is that if you want to refer to M1 in a file, you must import 1.proto, and if you want to refer to M2 in a file, you must import 2.proto. You do not need to explicitly import implicit/transitive dependencies. It's perfectly fine to use M2 without importing 1.proto.
The compiler actually follows the transitive imports and reads all three files in order to generate code for 3.proto. Moreover, in C++, 3.pb2.h will #include "2.pb2.h" which will in turn #include "1.pb2.h". The rule is only a syntax rule.
Why have this rule? Well, consider if you could directly use M1 in 3.proto without explicitly importing 1.proto, just because you imported 2.proto which itself imports 1.proto. Now consider if, later on, the maintainer of 2.proto decided to remove the field m_1. Now 2.proto doesn't use M1, so the maintainer decides to remove the import of 1.proto. But now 3.proto is broken, because it was relying on the fact that 2.proto imported 1.proto!
This is a common problem with C++ includes. I didn't want to have the same problem in Protobufs, so I made the rule that you must explicitly import all of the files declaring the types that you explicitly use in your own file.

Scala-IDE or Scala strange import behavior

I am working on a small Scala project. I have the following issue with 'import':
If, at the top of one of my files, I import two thing with these commands:
import main.Main._
import main.game.Game
^^^^
it gives me the following error message at the underlined 'main' word: "missing arguments for method main in object Main; follow this method with `_' if you want to treat it as a partially applied function" which is quite strange especially that it is just an import statement. And naturally no actual importing occures. At first I thought about semicolon inference quirks again but it is not the case. If I swap the two lines and write like this:
import main.game.Game
import main.Main._
then everythinng is fine.
Could anyone shed some light on that? Is it something special about Scala?
Presumably you have a main method in object Main. So after import main.Main._ main refers to this method instead of the main package. You could avoid it in several ways:
Change import order, as in the question.
Don't import the main method, as Daniel C. Sobral's answer suggests.
Explicitly say you want the top-level main package:
import _root_.main.game.Game
Following the normal Java package naming convention should avoid this problem in most cases, as you are unlikely to have members (or subpackages) called com or org (though net could be a problem).
You do have a method named main inside main.Main, don't you? Well, since you imported it, it has now shadowed the package by the name main. You can try this to confirm:
import main.Main.{main => _, _}
import main.game.Game
This will exclude main from being imported.

Scala's Relative Package Imports

I have a multi-project Scala workspace in eclipse. I think I'm getting hosed by my lack of understanding of the way Scala imports packages, but after spending more time than I care to admit looking for a solution, I can't figure this one out. I have recreated the problem in a simple 2 project setup.
Project 1: com.foo.mathematics contains a simple Vector class
Contains one file:
package com.foo.mathematics
class Vector2D(x : Double, y : Double) {
def length = math.sqrt(x*x + y*y)
}
Project 2: com.foo.analysis
package com.foo.analysis
import com.foo.mathematics.Vector2D
class Frame(xAxis : Vector2D, yAxis : Vector2D) {
}
Eclipse shows an error in the import line, The error message that I get is: Object mathematics is not a member of the package com.foo.
In the outline view, my import statement says this:
com.foo.analysis.<error: <none>>.Vector2D
I have tried changing the import to:
import mathematics.Vector2D
import _root_.com.foo.mathematics.Vector2D
neither one works...
What am I missing?
Both import com.foo.mathmatics.Vector2D and import _root_.com.foo.mathmatics.Vector2D should be fine. Most likely you either haven't added the first project to the build path of the second (see Build Path > Configure Build Path in the context menu), or need to clean the second project (Project > Build Clean) after making changes in the first project.
(Also, mathmatics looks like a typo for mathematics, so double check that you really have the same name in both places.)
Relative package imports don't come into it, they just mean you could write it this way:
package com.foo
package analysis
import mathmatics.Vector2D
class Frame(xAxis : Vector2D, yAxis : Vector2D) {
}